vendor: 4,521 bytes, lines 1-61
1/*! 2FullCalendar v5.11.0 3Docs & License: https://fullcalendar.io/ 4(c) 2021 Adam Shaw 5*/ 6var FullCalendar = (function (exports) { 7 'use strict'; 8 9 /*! ***************************************************************************** 10 Copyright (c) Microsoft Corporation. 11 12 Permission to use, copy, modify, and/or distribute this software for any 13 purpose with or without fee is hereby granted. 14 15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 16 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 17 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 18 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 19 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 PERFORMANCE OF THIS SOFTWARE. 22 ***************************************************************************** */ 23 /* global Reflect, Promise */ 24 25 var extendStatics = function(d, b) { 26 extendStatics = Object.setPrototypeOf || 27 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 28 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 29 return extendStatics(d, b); 30 }; 31 32 function __extends(d, b) { 33 if (typeof b !== "function" && b !== null) 34 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 35 extendStatics(d, b); 36 function __() { this.constructor = d; } 37 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 38 } 39 40 var __assign = function() { 41 __assign = Object.assign || function __assign(t) { 42 for (var s, i = 1, n = arguments.length; i < n; i++) { 43 s = arguments[i]; 44 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 45 } 46 return t; 47 }; 48 return __assign.apply(this, arguments); 49 }; 50 51 function __spreadArray(to, from, pack) { 52 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 53 if (ar || !(i in from)) { 54 if (!ar) ar = Array.prototype.slice.call(from, 0, i); 55 ar[i] = from[i]; 56 } 57 } 58 return to.concat(ar || from); 59 } 60 61 var n,u,i$1,t,o,r$1={},f$1=[],e$1=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function c$1(n,l){for(var u in l)n[u]=l[u];return n}function s(n){var l=n.parentNode;l&&l.removeChild(n);}function a$1(n,l,u){var i,t,o,r=arguments,f={};for(o in l)"key"==o?i=l[o]:"ref"==o?t=l[o]:f[o]=l[o];if(arguments.length>3)for(u=[u],o=3;o<arguments.length;o++)u.push(r[o]);if(null!=u&&(f.children=u),"function"==typeof n&&null!=n.defaultProps)for(o in n.defaultProps)void 0===f[o]&&(f[o]=n.defaultProps[o]);return v$1(n,f,i,t,null)}function v$1(l,u,i,t,o){var r={type:l,props:u,key:i,ref:t,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++n.__v:o};return null!=n.vnode&&n.vnode(r),r}function h(){return {current:null}}function y(n){return n.children}function p(n,l){this.props=n,this.context=l;}function d(n,l){if(null==l)return n.__?d(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?d(n):null}function _(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return _(n)}}function k(l){(!l.__d&&(l.__d=!0)&&u.push(l)&&!b$1.__r++||t!==n.debounceRendering)&&((t=n.debounceRendering)||i$1)(b$1);}function b$1(){for(var n;b$1.__r=u.length;)n=u.sort(function(n,l){return n.__v.__b-l.__v.__b}),u=[],n.some(function(n){var l,u,i,t,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=c$1({},t)).__v=t.__v+1,I$1(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?d(t):o,t.__h),T$1(u,t),t.__e!=o&&_(t)));});}function m(n,l,u,i,t,o,e,c,s,a){var h,p,_,k,b,m,w,A=i&&i.__k||f$1,P=A.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(k=u.__k[h]=null==(k=l[h])||"boolean"==typeof k?null:"string"==typeof k||"number"==typeof k||"bigint"==typeof k?v$1(null,k,null,null,k):Array.isArray(k)?v$1(y,{children:k},null,null,null):k.__b>
vendor: 7,710 bytes, line 61
610?v$1(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(_=A[h])||_&&k.key==_.key&&k.type===_.type)A[h]=void 0;else for(p=0;p<P;p++){if((_=A[p])&&k.key==_.key&&k.type===_.type){A[p]=void 0;break}_=null;}I$1(n,k,_=_||r$1,t,o,e,c,s,a),b=k.__e,(p=k.ref)&&_.ref!=p&&(w||(w=[]),_.ref&&w.push(_.ref,null,k),w.push(p,k.__c||b,k)),null!=b?(null==m&&(m=b),"function"==typeof k.type&&null!=k.__k&&k.__k===_.__k?k.__d=s=g$1(k,s,n):s=x$1(n,k,_,A,b,s),a||"option"!==u.type?"function"==typeof u.type&&(u.__d=s):n.value=""):s&&_.__e==s&&s.parentNode!=n&&(s=d(_));}for(u.__e=m,h=P;h--;)null!=A[h]&&("function"==typeof u.type&&null!=A[h].__e&&A[h].__e==u.__d&&(u.__d=d(i,h+1)),L$1(A[h],A[h]));if(w)for(h=0;h<w.length;h++)z(w[h],w[++h],w[++h]);}function g$1(n,l,u){var i,t;for(i=0;i<n.__k.length;i++)(t=n.__k[i])&&(t.__=n,l="function"==typeof t.type?g$1(t,l,u):x$1(u,t,t,n.__k,t.__e,l));return l}function w$1(n,l){return l=l||[],null==n||"boolean"==typeof n||(Array.isArray(n)?n.some(function(n){w$1(n,l);}):l.push(n)),l}function x$1(n,l,u,i,t,o){var r,f,e;if(void 0!==l.__d)r=l.__d,l.__d=void 0;else if(null==u||t!=o||null==t.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(t),r=null;else {for(f=o,e=0;(f=f.nextSibling)&&e<i.length;e+=2)if(f==t)break n;n.insertBefore(t,o),r=o;}return void 0!==r?r:t.nextSibling}function A$1(n,l,u,i,t){var o;for(o in u)"children"===o||"key"===o||o in l||C$1(n,o,null,u[o],i);for(o in l)t&&"function"!=typeof l[o]||"children"===o||"key"===o||"value"===o||"checked"===o||u[o]===l[o]||C$1(n,o,l[o],u[o],i);}function P$1(n,l,u){"-"===l[0]?n.setProperty(l,u):n[l]=null==u?"":"number"!=typeof u||e$1.test(l)?u:u+"px";}function C$1(n,l,u,i,t){var o;n:if("style"===l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof i&&(n.style.cssText=i=""),i)for(l in i)u&&l in u||P$1(n.style,l,"");if(u)for(l in u)i&&u[l]===i[l]||P$1(n.style,l,u[l]);}else if("o"===l[0]&&"n"===l[1])o=l!==(l=l.replace(/Capture$/,"")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?i||n.addEventListener(l,o?H$1:$$1,o):n.removeEventListener(l,o?H$1:$$1,o);else if("dangerouslySetInnerHTML"!==l){if(t)l=l.replace(/xlink[H:h]/,"h").replace(/sName$/,"s");else if("href"!==l&&"list"!==l&&"form"!==l&&"tabIndex"!==l&&"download"!==l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null!=u&&(!1!==u||"a"===l[0]&&"r"===l[1])?n.setAttribute(l,u):n.removeAttribute(l));}}function $$1(l){this.l[l.type+!1](n.event?n.event(l):l);}function H$1(l){this.l[l.type+!0](n.event?n.event(l):l);}function I$1(l,u,i,t,o,r,f,e,s){var a,v,h,d,_,k,b,g,w,x,A,P=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(s=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(a=n.__b)&&a(u);try{n:if("function"==typeof P){if(g=u.props,w=(a=P.contextType)&&t[a.__c],x=a?w?w.props.value:a.__:t,i.__c?b=(v=u.__c=i.__c).__=v.__E:("prototype"in P&&P.prototype.render?u.__c=v=new P(g,x):(u.__c=v=new p(g,x),v.constructor=P,v.render=M$1),w&&w.sub(v),v.props=g,v.state||(v.state={}),v.context=x,v.__n=t,h=v.__d=!0,v.__h=[]),null==v.__s&&(v.__s=v.state),null!=P.getDerivedStateFromProps&&(v.__s==v.state&&(v.__s=c$1({},v.__s)),c$1(v.__s,P.getDerivedStateFromProps(g,v.__s))),d=v.props,_=v.state,h)null==P.getDerivedStateFromProps&&null!=v.componentWillMount&&v.componentWillMount(),null!=v.componentDidMount&&v.__h.push(v.componentDidMount);else {if(null==P.getDerivedStateFromProps&&g!==d&&null!=v.componentWillReceiveProps&&v.componentWillReceiveProps(g,x),!v.__e&&null!=v.shouldComponentUpdate&&!1===v.shouldComponentUpdate(g,v.__s,x)||u.__v===i.__v){v.props=g,v.state=v.__s,u.__v!==i.__v&&(v.__d=!1),v.__v=u,u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u);}),v.__h.length&&f.push(v);break n}null!=v.componentWillUpdate&&v.componentWillUpdate(g,v.__s,x),null!=v.componentDidUpdate&&v.__h.push(function(){v.componentDidUpdate(d,_,k);});}v.context=x,v.props=g,v.state=v.__s,(a=n.__r)&&a(u),v.__d=!1,v.__v=u,v.__P=l,a=v.render(v.props,v.state,v.context),v.state=v.__s,null!=v.getChildContext&&(t=c$1(c$1({},t),v.getChildContext())),h||null==v.getSnapshotBeforeUpdate||(k=v.getSnapshotBeforeUpdate(d,_)),A=null!=a&&a.type===y&&null==a.key?a.props.children:a,m(l,Array.isArray(A)?A:[A],u,i,t,o,r,f,e,s),v.base=u.__e,u.__h=null,v.__h.length&&f.push(v),b&&(v.__E=v.__=null),v.__e=!1;}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=j$2(i.__e,u,i,t,o,r,f,s);(a=n.diffed)&&a(u);}catch(l){u.__v=null,(s||null!=r)&&(u.__e=e,u.__h=!!s,r[r.indexOf(e)]=null),n.__e(l,u,i);}}function T$1(l,u){n.__c&&n.__c(u,l),l.some(function(u){try{l=u.__h,u.__h=[],l.some(function(n){n.call(u);});}catch(l){n.__e(l,u.__v);}});}function j$2(n,l,u,i,t,o,e,c){var a,v,h,y,p=u.props,d=l.props,_=l.type,k=0;if("svg"===_&&(t=!0),null!=o)for(;k<o.length;k++)if((a=o[k])&&(a===n||(_?a.localName==_:3==a.nodeType))){n=a,o[k]=null;break}if(null==n){if(null===_)return document.createTextNode(d);n=t?document.createElementNS("http://www.w3.org/2000/svg",_):document.createElement(_,d.is&&d),o=null,c=!1;}if(null===_)p===d||c&&n.data===d||(n.data=d);else {if(o=o&&f$1.slice.call(n.childNodes),v=(p=u.props||r$1).dangerouslySetInnerHTML,h=d.dangerouslySetInnerHTML,!c){if(null!=o)for(p={},y=0;y<n.attributes.length;y++)p[n.attributes[y].name]=n.attributes[y].value;(h||v)&&(h&&(v&&h.__html==v.__html||h.__html===n.innerHTML)||(n.innerHTML=h&&h.__html||""));}if(A$1(n,d,p,t,c),h)l.__k=[];else if(k=l.props.children,m(n,Array.isArray(k)?k:[k],l,u,i,t&&"foreignObject"!==_,o,e,n.firstChild,c),null!=o)for(k=o.length;k--;)null!=o[k]&&s(o[k]);c||("value"in d&&void 0!==(k=d.value)&&(k!==n.value||"progress"===_&&!k)&&C$1(n,"value",k,p.value,!1),"checked"in d&&void 0!==(k=d.checked)&&k!==n.checked&&C$1(n,"checked",k,p.checked,!1));}return n}function z(l,u,i){try{"function"==typeof l?l(u):l.current=u;}catch(l){n.__e(l,i);}}function L$1(l,u,i){var t,o,r;if(n.unmount&&n.unmount(l),(t=l.ref)&&(t.current&&t.current!==l.__e||z(t,null,u)),i||"function"==typeof l.type||(i=null!=(o=l.__e)),l.__e=l.__d=void 0,null!=(t=l.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount();}catch(l){n.__e(l,u);}t.base=t.__P=null;}if(t=l.__k)for(r=0;r<t.length;r++)t[r]&&L$1(t[r],u,i);null!=o&&s(o);}function M$1(n,l,u){return this.constructor(n,u)}function N(l,u,i){var t,o,e;n.__&&n.__(l,u),o=(t="function"==typeof i)?null:i&&i.__k||u.__k,e=[],I$1(u,l=(!t&&i||u).__k=a$1(y,null,[l]),o||r$1,r$1,void 0!==u.ownerSVGElement,!t&&i?[i]:o?null:u.firstChild?f$1.slice.call(u.childNodes):null,e,!t&&i?i:o?o.__e:u.firstChild,t),T$1(e,l);}function q(n,l){var u={__c:l="__cC"+o++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(k);},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n);};}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n={__e:function(n,l){for(var u,i,t;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return u.__E=u}catch(l){n=l;}throw n},__v:0},p.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=c$1({},this.state),"function"==typeof n&&(n=n(c$1({},u),this.props)),n&&c$1(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),k(this));},p.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),k(this));},p.prototype.render=y,u=[],i$1="function"==typeof Promise?Promise.prototype.then.bind(Prom
vendor: 5,077 bytes, lines 61-65
61ise.resolve()):setTimeout,b$1.__r=0,o=0; 62 63 var r,i=[],c=n.__b,f=n.__r,e=n.diffed,a=n.__c,v=n.unmount;function x(){i.forEach(function(t){if(t.__P)try{t.__H.__h.forEach(g),t.__H.__h.forEach(j$1),t.__H.__h=[];}catch(u){t.__H.__h=[],n.__e(u,t.__v);}}),i=[];}n.__b=function(n){c&&c(n);},n.__r=function(n){f&&f(n);var r=(n.__c).__H;r&&(r.__h.forEach(g),r.__h.forEach(j$1),r.__h=[]);},n.diffed=function(t){e&&e(t);var o=t.__c;o&&o.__H&&o.__H.__h.length&&(1!==i.push(o)&&r===n.requestAnimationFrame||((r=n.requestAnimationFrame)||function(n){var t,u=function(){clearTimeout(r),b&&cancelAnimationFrame(t),setTimeout(n);},r=setTimeout(u,100);b&&(t=requestAnimationFrame(u));})(x));},n.__c=function(t,u){u.some(function(t){try{t.__h.forEach(g),t.__h=t.__h.filter(function(n){return !n.__||j$1(n)});}catch(r){u.some(function(n){n.__h&&(n.__h=[]);}),u=[],n.__e(r,t.__v);}}),a&&a(t,u);},n.unmount=function(t){v&&v(t);var u=t.__c;if(u&&u.__H)try{u.__H.__.forEach(g);}catch(t){n.__e(t,u.__v);}};var b="function"==typeof requestAnimationFrame;function g(n){"function"==typeof n.__c&&n.__c();}function j$1(n){n.__c=n.__();} 64 65 function C(n,t){for(var e in t)n[e]=t[e];return n}function S(n,t){for(var e in n)if("__source"!==e&&!(e in t))return !0;for(var r in t)if("__source"!==r&&n[r]!==t[r])return !0;return !1}function E(n){this.props=n;}(E.prototype=new p).isPureReactComponent=!0,E.prototype.shouldComponentUpdate=function(n,t){return S(this.props,n)||S(this.state,t)};var w=n.__b;n.__b=function(n){n.type&&n.type.__f&&n.ref&&(n.props.ref=n.ref,n.ref=null),w&&w(n);};var A=n.__e;n.__e=function(n,t,e){if(n.then)for(var r,u=t;u=u.__;)if((r=u.__c)&&r.__c)return null==t.__e&&(t.__e=e.__e,t.__k=e.__k),r.__c(n,t);A(n,t,e);};var O=n.unmount;function L(){this.__u=0,this.t=null,this.__b=null;}function U(n){var t=n.__.__c;return t&&t.__e&&t.__e(n)}function F(){this.u=null,this.o=null;}n.unmount=function(n){var t=n.__c;t&&t.__R&&t.__R(),t&&!0===n.__h&&(n.type=null),O&&O(n);},(L.prototype=new p).__c=function(n,t){var e=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(e);var u=U(r.__v),o=!1,i=function(){o||(o=!0,e.__R=null,u?u(l):l());};e.__R=i;var l=function(){if(!--r.__u){if(r.state.__e){var n=r.state.__e;r.__v.__k[0]=function n(t,e,r){return t&&(t.__v=null,t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)}),t.__c&&t.__c.__P===e&&(t.__e&&r.insertBefore(t.__e,t.__d),t.__c.__e=!0,t.__c.__P=r)),t}(n,n.__c.__P,n.__c.__O);}var t;for(r.setState({__e:r.__b=null});t=r.t.pop();)t.forceUpdate();}},f=!0===t.__h;r.__u++||f||r.setState({__e:r.__b=r.__v.__k[0]}),n.then(i,i);},L.prototype.componentWillUnmount=function(){this.t=[];},L.prototype.render=function(n,t){if(this.__b){if(this.__v.__k){var e=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=function n(t,e,r){return t&&(t.__c&&t.__c.__H&&(t.__c.__H.__.forEach(function(n){"function"==typeof n.__c&&n.__c();}),t.__c.__H=null),null!=(t=C({},t)).__c&&(t.__c.__P===r&&(t.__c.__P=e),t.__c=null),t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)})),t}(this.__b,e,r.__O=r.__P);}this.__b=null;}var u=t.__e&&a$1(y,null,n.fallback);return u&&(u.__h=null),[a$1(y,null,t.__e?null:n.children),u]};var M=function(n,t,e){if(++e[1]===e[0]&&n.o.delete(t),n.props.revealOrder&&("t"!==n.props.revealOrder[0]||!n.o.size))for(e=n.u;e;){for(;e.length>3;)e.pop()();if(e[1]<e[0])break;n.u=e=e[2];}};function T(n){return this.getChildContext=function(){return n.context},n.children}function j(n){var t=this,e=n.i;t.componentWillUnmount=function(){N(null,t.l),t.l=null,t.i=null;},t.i&&t.i!==e&&t.componentWillUnmount(),n.__v?(t.l||(t.i=e,t.l={nodeType:1,parentNode:e,childNodes:[],appendChild:function(n){this.childNodes.push(n),t.i.appendChild(n);},insertBefore:function(n,e){this.childNodes.push(n),t.i.appendChild(n);},removeChild:function(n){this.childNodes.splice(this.childNodes.indexOf(n)>>>1,1),t.i.removeChild(n);}}),N(a$1(T,{context:t.context},n.__v),t.l)):t.l&&t.componentWillUnmount();}function I(n,t){return a$1(j,{__v:n,i:t})}(F.prototype=new p).__e=function(n){var t=this,e=U(t.__v),r=t.o.get(n);return r[0]++,function(u){var o=function(){t.props.revealOrder?(r.push(u),M(t,n,r)):u();};e?e(o):o();}},F.prototype.render=function(n){this.u=null,this.o=new Map;var t=w$1(n.children);n.revealOrder&&"b"===n.revealOrder[0]&&t.reverse();for(var e=t.length;e--;)this.o.set(t[e],this.u=[1,0,this.u]);return n.children},F.prototype.componentDidUpdate=F.prototype.componentDidMount=function(){var n=this;this.o.forEach(function(t,e){M(n,e,t);});};var W="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,P=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,V=function(n){return ("undefined"!=typeof Symbol&&"symbol"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(n)};p.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach(function(n){Object.defineProperty(p.prototype,n,{
65configurable:!0,get:function(){return this["UNSAFE_"+n]},set:function(t){Object.defineProperty(this,n,{configurable:!0,writable:!0,value:t});}});});var H=n.event;function Z(){}function Y(){return this.cancelBubble}function $(){return this.defaultPrevented}n.event=function(n){return H&&(n=H(n)),n.persist=Z,n.isPropagationStopped=Y,n.isDefaultPrevented=$,n.nativeEvent=n};var G={configurable:!0,get:function(){return this.class}},J=n.vnode;n.vnode=function(n){var t=n.type,e=n.props,r=e;if("string"==typeof t){for(var u in r={},e){var o=e[u];"value"===u&&"defaultValue"in e&&null==o||("defaultValue"===u&&"value"in e&&null==e.value?u="value":"download"===u&&!0===o?o="":/ondoubleclick/i.test(u)?u="ondblclick":/^onchange(textarea|input)/i.test(u+t)&&!V(e.type)?u="oninput":/^on(Ani|Tra|Tou|BeforeInp)/.test(u)?u=u.toLowerCase():P.test(u)?u=u.replace(/[A-Z0-9]/,"-$&").toLowerCase():null===o&&(o=void 0),r[u]=o);}"select"==t&&r.multiple&&Array.isArray(r.value)&&(r.value=w$1(e.children).forEach(function(n){n.props.selected=-1!=r.value.indexOf(n.props.value);})),"select"==t&&null!=r.defaultValue&&(r.value=w$1(e.children).forEach(function(n){n.props.selected=r.multiple?-1!=r.defaultValue.indexOf(n.props.value):r.defaultValue==n.props.value;})),n.props=r;}t&&e.class!=e.className&&(G.enumerable="className"in e,null!=e.className&&(r.class=e.className),Object.defineProperty(r,"className",G)),n.$$typeof=W,J&&J(n);};var K=n.__r;n.__r=function(n){K&&K(n);};"object"==typeof performance&&"function"==typeof performance.now?performance.now.bind(performance):function(){return Date.now()}; 66 67 var globalObj = typeof globalThis !== 'undefined' ? globalThis : window; // // TODO: streamline when killing IE11 support 68 if (globalObj.FullCalendarVDom) { 69 console.warn('FullCalendar VDOM already loaded'); 70 } 71 else { 72 globalObj.FullCalendarVDom = { 73 Component: p, 74 createElement: a$1, 75 render: N, 76 createRef: h, 77 Fragment: y, 78 createContext: createContext$1, 79 createPortal: I, 80 flushSync: flushSync$1, 81 unmountComponentAtNode: unmountComponentAtNode$1, 82 }; 83 } 84 // HACKS... 85 // TODO: lock version 86 // TODO: link gh issues 87 function flushSync$1(runBeforeFlush) { 88 runBeforeFlush(); 89 var oldDebounceRendering = n.debounceRendering; // orig 90 var callbackQ = []; 91 function execCallbackSync(callback) { 92 callbackQ.push(callback); 93 } 94 n.debounceRendering = execCallbackSync; 95 N(a$1(FakeComponent, {}), document.createElement('div')); 96 while (callbackQ.length) { 97 callbackQ.shift()(); 98 } 99 n.debounceRendering = oldDebounceRendering; 100 } 101 var FakeComponent = /** @class */ (function (_super) { 102 __extends(FakeComponent, _super); 103 function FakeComponent() { 104 return _super !== null && _super.apply(this, arguments) || this; 105 } 106 FakeComponent.prototype.render = function () { return a$1('div', {}); }; 107 FakeComponent.prototype.componentDidMount = function () { this.setState({}); }; 108 return FakeComponent; 109 }(p)); 110 function createContext$1(defaultValue) { 111 var ContextType = q(defaultValue); 112 var origProvider = ContextType.Provider; 113 ContextType.Provider = function () { 114 var _this = this; 115 var isNew = !this.getChildContext; 116 var children = origProvider.apply(this, arguments); // eslint-disable-line prefer-rest-params 117 if (isNew) { 118 var subs_1 = []; 119 this.shouldComponentUpdate = function (_props) { 120 if (_this.props.value !== _props.value) { 121 subs_1.forEach(function (c) { 122 c.context = _props.value; 123 c.forceUpdate(); 124 }); 125 } 126 }; 127 this.sub = function (c) { 128 subs_1.push(c); 129 var old = c.componentWillUnmount; 130 c.componentWillUnmount = function () { 131 subs_1.splice(subs_1.indexOf(c), 1); 132 old && old.call(c); 133 }; 134 }; 135 } 136 return children; 137 }; 138 return ContextType; 139 } 140 function unmountComponentAtNode$1(node) { 141 N(null, node); 142 } 143 144 // no public types yet. when there are, export from: 145 // import {} from './api-type-deps' 146 var EventSourceApi = /** @class */ (function () { 147 function EventSourceApi(context, internalEventSource) { 148 this.context = context; 149 this.internalEventSource = internalEventSource; 150 } 151 EventSourceApi.prototype.remove = function () { 152 this.context.dispatch({
153 type: 'REMOVE_EVENT_SOURCE', 154 sourceId: this.internalEventSource.sourceId, 155 }); 156 }; 157 EventSourceApi.prototype.refetch = function () { 158 this.context.dispatch({ 159 type: 'FETCH_EVENT_SOURCES', 160 sourceIds: [this.internalEventSource.sourceId], 161 isRefetch: true, 162 }); 163 }; 164 Object.defineProperty(EventSourceApi.prototype, "id", { 165 get: function () { 166 return this.internalEventSource.publicId; 167 }, 168 enumerable: false, 169 configurable: true 170 }); 171 Object.defineProperty(EventSourceApi.prototype, "url", { 172 get: function () { 173 return this.internalEventSource.meta.url; 174 }, 175 enumerable: false, 176 configurable: true 177 }); 178 Object.defineProperty(EventSourceApi.prototype, "format", { 179 get: function () { 180 return this.internalEventSource.meta.format; // TODO: bad. not guaranteed 181 }, 182 enumerable: false, 183 configurable: true 184 }); 185 return EventSourceApi; 186 }()); 187 188 function removeElement(el) { 189 if (el.parentNode) { 190 el.parentNode.removeChild(el); 191 } 192 } 193 // Querying 194 // ---------------------------------------------------------------------------------------------------------------- 195 function elementClosest(el, selector) { 196 if (el.closest) { 197 return el.closest(selector); 198 // really bad fallback for IE 199 // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest 200 } 201 if (!document.documentElement.contains(el)) { 202 return null; 203 } 204 do { 205 if (elementMatches(el, selector)) { 206 return el; 207 } 208 el = (el.parentElement || el.parentNode); 209 } while (el !== null && el.nodeType === 1); 210 return null; 211 } 212 function elementMatches(el, selector) { 213 var method = el.matches || el.matchesSelector || el.msMatchesSelector; 214 return method.call(el, selector); 215 } 216 // accepts multiple subject els 217 // returns a real array. good for methods like forEach 218 // TODO: accept the document 219 function findElements(container, selector) { 220 var containers = container instanceof HTMLElement ? [container] : container; 221 var allMatches = []; 222 for (var i = 0; i < containers.length; i += 1) { 223 var matches = containers[i].querySelectorAll(selector); 224 for (var j = 0; j < matches.length; j += 1) { 225 allMatches.push(matches[j]); 226 } 227 } 228 return allMatches; 229 } 230 // accepts multiple subject els 231 // only queries direct child elements // TODO: rename to findDirectChildren! 232 function findDirectChildren(parent, selector) { 233 var parents = parent instanceof HTMLElement ? [parent] : parent; 234 var allMatches = []; 235 for (var i = 0; i < parents.length; i += 1) { 236 var childNodes = parents[i].children; // only ever elements 237 for (var j = 0; j < childNodes.length; j += 1) { 238 var childNode = childNodes[j]; 239 if (!selector || elementMatches(childNode, selector)) { 240 allMatches.push(childNode); 241 } 242 } 243 } 244 return allMatches; 245 } 246 // Style 247 // ---------------------------------------------------------------------------------------------------------------- 248 var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i; 249 function applyStyle(el, props) { 250 for (var propName in props) { 251 applyStyleProp(el, propName, props[propName]); 252 } 253 } 254 function applyStyleProp(el, name, val) { 255 if (val == null) { 256 el.style[name] = ''; 257 } 258 else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) { 259 el.style[name] = val + "px"; 260 } 261 else { 262 el.style[name] = val; 263 } 264 } 265 // Event Handling 266 // ---------------------------------------------------------------------------------------------------------------- 267 // if intercepting bubbled events at the document/window/body level, 268 // and want to see originating element (the 'target'), use this util instead 269 // of `ev.target` because it goes within web-component boundaries. 270 function getEventTargetViaRoot(ev) { 271 var _a, _b; 272 return (_b = (_a = ev.composedPath) === null || _a === void 0 ? void 0 : _a.call(ev)[0]) !== null && _b !== void 0 ? _b : ev.target; 273 } 274 // Shadow DOM consuderations 275 // ---------------------------------------------------------------------------------------------------------------- 276 function getElRoot(el) { 277 return el.getRootNode ? el.getRootNode() : document; 278 } 279 // Unique ID for DOM attribute 280 var guid$1 = 0; 281 function getUniqueDomId() { 282 guid$1 += 1; 283 return 'fc-dom-' + guid$1; 284 } 285 286 // Stops a mouse/touch event from doing it's native browser action 287 function preventDefault(ev) { 288 ev.preventDefault(); 289 } 290 // Event Delegation 291 // ---------------------------------------------------------------------------------------------------------------- 292 function buildDelegationHandler(selector, handler) { 293 return function (ev) {
294 var matchedChild = elementClosest(ev.target, selector); 295 if (matchedChild) { 296 handler.call(matchedChild, ev, matchedChild); 297 } 298 }; 299 } 300 function listenBySelector(container, eventType, selector, handler) { 301 var attachedHandler = buildDelegationHandler(selector, handler); 302 container.addEventListener(eventType, attachedHandler); 303 return function () { 304 container.removeEventListener(eventType, attachedHandler); 305 }; 306 } 307 function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) { 308 var currentMatchedChild; 309 return listenBySelector(container, 'mouseover', selector, function (mouseOverEv, matchedChild) { 310 if (matchedChild !== currentMatchedChild) { 311 currentMatchedChild = matchedChild; 312 onMouseEnter(mouseOverEv, matchedChild); 313 var realOnMouseLeave_1 = function (mouseLeaveEv) { 314 currentMatchedChild = null; 315 onMouseLeave(mouseLeaveEv, matchedChild); 316 matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1); 317 }; 318 // listen to the next mouseleave, and then unattach 319 matchedChild.addEventListener('mouseleave', realOnMouseLeave_1); 320 } 321 }); 322 } 323 // Animation 324 // ---------------------------------------------------------------------------------------------------------------- 325 var transitionEventNames = [ 326 'webkitTransitionEnd', 327 'otransitionend', 328 'oTransitionEnd', 329 'msTransitionEnd', 330 'transitionend', 331 ]; 332 // triggered only when the next single subsequent transition finishes 333 function whenTransitionDone(el, callback) { 334 var realCallback = function (ev) { 335 callback(ev); 336 transitionEventNames.forEach(function (eventName) { 337 el.removeEventListener(eventName, realCallback); 338 }); 339 }; 340 transitionEventNames.forEach(function (eventName) { 341 el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes 342 }); 343 } 344 // ARIA workarounds 345 // ---------------------------------------------------------------------------------------------------------------- 346 function createAriaClickAttrs(handler) { 347 return __assign({ onClick: handler }, createAriaKeyboardAttrs(handler)); 348 } 349 function createAriaKeyboardAttrs(handler) { 350 return { 351 tabIndex: 0, 352 onKeyDown: function (ev) { 353 if (ev.key === 'Enter' || ev.key === ' ') { 354 handler(ev); 355 ev.preventDefault(); // if space, don't scroll down page 356 } 357 }, 358 }; 359 } 360 361 var guidNumber = 0; 362 function guid() { 363 guidNumber += 1; 364 return String(guidNumber); 365 } 366 /* FullCalendar-specific DOM Utilities 367 ----------------------------------------------------------------------------------------------------------------------*/ 368 // Make the mouse cursor express that an event is not allowed in the current area 369 function disableCursor() { 370 document.body.classList.add('fc-not-allowed'); 371 } 372 // Returns the mouse cursor to its original look 373 function enableCursor() { 374 document.body.classList.remove('fc-not-allowed'); 375 } 376 /* Selection 377 ----------------------------------------------------------------------------------------------------------------------*/ 378 function preventSelection(el) { 379 el.classList.add('fc-unselectable'); 380 el.addEventListener('selectstart', preventDefault); 381 } 382 function allowSelection(el) { 383 el.classList.remove('fc-unselectable'); 384 el.removeEventListener('selectstart', preventDefault); 385 } 386 /* Context Menu 387 ----------------------------------------------------------------------------------------------------------------------*/ 388 function preventContextMenu(el) { 389 el.addEventListener('contextmenu', preventDefault); 390 } 391 function allowContextMenu(el) { 392 el.removeEventListener('contextmenu', preventDefault); 393 } 394 function parseFieldSpecs(input) { 395 var specs = []; 396 var tokens = []; 397 var i; 398 var token; 399 if (typeof input === 'string') { 400 tokens = input.split(/\s*,\s*/); 401 } 402 else if (typeof input === 'function') { 403 tokens = [input]; 404 } 405 else if (Array.isArray(input)) { 406 tokens = input; 407 } 408 for (i = 0; i < tokens.length; i += 1) { 409 token = tokens[i]; 410 if (typeof token === 'string') { 411 specs.push(token.charAt(0) === '-' ? 412 { field: token.substring(1), order: -1 } : 413 { field: token, order: 1 }); 414 } 415 else if (typeof token === 'function') { 416 specs.push({ func: token }); 417 } 418 } 419 return specs; 420 } 421 function compareByFieldSpecs(obj0, obj1, fieldSpecs) { 422 var i; 423 var cmp; 424 for (i = 0; i < fieldSpecs.length; i += 1) { 425 cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]); 426 if (cmp) { 427 return cmp; 428 } 429 } 430 return 0; 431 } 432 function compareByFieldSpec(obj0, obj1, fieldSpec) { 433 if (fieldSpec.func) { 434 return fieldSpec.func(obj0, obj1); 435 } 436 return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field]) 437 * (fieldSpec.order || 1); 438 } 439 function flexibleCompare(a, b) { 440 if (!a && !b) { 441 return 0; 442 } 443 if (b == null) { 444 return -1; 445 } 446 if (a == null) { 447 return 1; 448 } 449 if (typeof a === 'string' || typeof b === 'string') { 450 return String(a).localeCompare(String(b)); 451 } 452 return a - b; 453 } 454 /* String Utilities 455 ----------------------------------------------------------------------------------------------------------------------*/ 456 function padStart(val, len) { 457 var s = String(val); 458 return '000'.substr(0, len - s.length) + s; 459 } 460 function formatWithOrdinals(formatter, args, fallbackText) { 461 if (typeof formatter === 'function') { 462 return formatter.apply(void 0, args); 463 } 464 if (typeof formatter === 'string') { // non-blank string 465 return args.reduce(function (str, arg, index) { return (str.replace('$' + index, arg || '')); }, formatter); 466 } 467 return fallbackText; 468 } 469 /* Number Utilities 470 ----------------------------------------------------------------------------------------------------------------------*/ 471 function compareNumbers(a, b) { 472 return a - b; 473 } 474 function isInt(n) { 475 return n % 1 === 0; 476 } 477 /* FC-specific DOM dimension stuff 478 ----------------------------------------------------------------------------------------------------------------------*/ 479 function computeSmallestCellWidth(cellEl) { 480 var allWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-frame'); 481 var contentWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-cushion'); 482 if (!allWidthEl) { 483 throw new Error('needs fc-scrollgrid-shrink-frame className'); // TODO: use const 484 } 485 if (!contentWidthEl) { 486 throw new Error('needs fc-scrollgrid-shrink-cushion className'); 487 } 488 return cellEl.getBoundingClientRect().width - allWidthEl.getBoundingClientRect().width + // the cell padding+border 489 contentWidthEl.getBoundingClientRect().width; 490 } 491 492 var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; 493 // Adding 494 function addWeeks(m, n) { 495 var a = dateToUtcArray(m); 496 a[2] += n * 7; 497 return arrayToUtcDate(a); 498 } 499 function addDays(m, n) { 500 var a = dateToUtcArray(m); 501 a[2] += n; 502 return arrayToUtcDate(a); 503 } 504 function addMs(m, n) { 505 var a = dateToUtcArray(m); 506 a[6] += n; 507 return arrayToUtcDate(a); 508 } 509 // Diffing (all return floats) 510 // TODO: why not use ranges? 511 function diffWeeks(m0, m1) { 512 return diffDays(m0, m1) / 7; 513 } 514 function diffDays(m0, m1) { 515 return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24); 516 } 517 function diffHours(m0, m1) { 518 return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60); 519 } 520 function diffMinutes(m0, m1) { 521 return (m1.valueOf() - m0.valueOf()) / (1000 * 60); 522 } 523 function diffSeconds(m0, m1) { 524 return (m1.valueOf() - m0.valueOf()) / 1000; 525 } 526 function diffDayAndTime(m0, m1) { 527 var m0day = startOfDay(m0); 528 var m1day = startOfDay(m1); 529 return { 530 years: 0, 531 months: 0, 532 days: Math.round(diffDays(m0day, m1day)), 533 milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf()), 534 }; 535 } 536 // Diffing Whole Units 537 function diffWholeWeeks(m0, m1) { 538 var d = diffWholeDays(m0, m1); 539 if (d !== null && d % 7 === 0) { 540 return d / 7; 541 } 542 return null; 543 } 544 function diffWholeDays(m0, m1) { 545 if (timeAsMs(m0) === timeAsMs(m1)) { 546 return Math.round(diffDays(m0, m1)); 547 } 548 return null; 549 } 550 // Start-Of 551 function startOfDay(m) { 552 return arrayToUtcDate([ 553 m.getUTCFullYear(), 554 m.getUTCMonth(), 555 m.getUTCDate(), 556 ]); 557 } 558 function startOfHour(m) { 559 return arrayToUtcDate([ 560 m.getUTCFullYear(), 561 m.getUTCMonth(), 562 m.getUTCDate(), 563 m.getUTCHours(), 564 ]); 565 } 566 function startOfMinute(m) { 567 return arrayToUtcDate([ 568 m.getUTCFullYear(), 569 m.getUTCMonth(), 570 m.getUTCDate(), 571 m.getUTCHours(), 572 m.getUTCMinutes(), 573 ]); 574 } 575 function startOfSecond(m) { 576 return arrayToUtcDate([ 577 m.getUTCFullYear(), 578 m.getUTCMonth(), 579 m.getUTCDate(), 580 m.getUTCHours(), 581 m.getUTCMinutes(), 582 m.getUTCSeconds(), 583 ]); 584 } 585 // Week Computation 586 function weekOfYear(marker, dow, doy) { 587 var y = marker.getUTCFullYear(); 588 var w = weekOfGivenYear(marker, y, dow, doy); 589 if (w < 1) { 590 return weekOfGivenYear(marker, y - 1, dow, doy); 591 } 592 var nextW = weekOfGivenYear(marker, y + 1, dow, doy); 593 if (nextW >= 1) { 594 return Math.min(w, nextW); 595 } 596 return w; 597 } 598 function weekOfGivenYear(marker, year, dow, doy) { 599 var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]); 600 var dayStart = startOfDay(marker); 601 var days = Math.round(diffDays(firstWeekStart, dayStart)); 602 return Math.floor(days / 7) + 1; // zero-indexed 603 } 604 // start-of-first-week - start-of-year 605 function firstWeekOffset(year, dow, doy) { 606 // first-week day -- which january is always in the first week (4 for iso, 1 for other) 607 var fwd = 7 + dow - doy; 608 // first-week day local weekday -- which local weekday is fwd 609 var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7; 610 return -fwdlw + fwd - 1; 611 } 612 // Array Conversion 613 function dateToLocalArray(date) { 614 return [ 615 date.getFullYear(), 616 date.getMonth(), 617 date.getDate(), 618 date.getHours(), 619 date.getMinutes(), 620 date.getSeconds(), 621 date.getMilliseconds(), 622 ]; 623 } 624 function arrayToLocalDate(a) { 625 return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month 626 a[3] || 0, a[4] || 0, a[5] || 0); 627 } 628 function dateToUtcArray(date) { 629 return [ 630 date.getUTCFullYear(), 631 date.getUTCMonth(), 632 date.getUTCDate(), 633 date.getUTCHours(), 634 date.getUTCMinutes(), 635 date.getUTCSeconds(), 636 date.getUTCMilliseconds(), 637 ]; 638 } 639 function arrayToUtcDate(a) { 640 // according to web standards (and Safari), a month index is required. 641 // massage if only given a year. 642 if (a.length === 1) { 643 a = a.concat([0]); 644 } 645 return new Date(Date.UTC.apply(Date, a)); 646 } 647 // Other Utils 648 function isValidDate(m) { 649 return !isNaN(m.valueOf()); 650 } 651 function timeAsMs(m) { 652 return m.getUTCHours() * 1000 * 60 * 60 + 653 m.getUTCMinutes() * 1000 * 60 + 654 m.getUTCSeconds() * 1000 + 655 m.getUTCMilliseconds(); 656 } 657 658 function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) { 659 return { 660 instanceId: guid(), 661 defId: defId, 662 range: range, 663 forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo, 664 forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo, 665 }; 666 } 667 668 var hasOwnProperty = Object.prototype.hasOwnProperty; 669 // Merges an array of objects into a single object. 670 // The second argument allows for an array of property names who's object values will be merged together. 671 function mergeProps(propObjs, complexPropsMap) { 672 var dest = {}; 673 if (complexPropsMap) { 674 for (var name_1 in complexPropsMap) { 675 var complexObjs = []; 676 // collect the trailing object values, stopping when a non-object is discovered 677 for (var i = propObjs.length - 1; i >= 0; i -= 1) { 678 var val = propObjs[i][name_1]; 679 if (typeof val === 'object' && val) { // non-null object 680 complexObjs.unshift(val); 681 } 682 else if (val !== undefined) { 683 dest[name_1] = val; // if there were no objects, this value will be used 684 break; 685 } 686 } 687 // if the trailing values were objects, use the merged value 688 if (complexObjs.length) { 689 dest[name_1] = mergeProps(complexObjs); 690 } 691 } 692 } 693 // copy values into the destination, going from last to first 694 for (var i = propObjs.length - 1; i >= 0; i -= 1) { 695 var props = propObjs[i]; 696 for (var name_2 in props) { 697 if (!(name_2 in dest)) { // if already assigned by previous props or complex props, don't reassign 698 dest[name_2] = props[name_2]; 699 } 700 } 701 } 702 return dest; 703 } 704 function filterHash(hash, func) { 705 var filtered = {}; 706 for (var key in hash) { 707 if (func(hash[key], key)) { 708 filtered[key] = hash[key]; 709 } 710 } 711 return filtered; 712 } 713 function mapHash(hash, func) { 714 var newHash = {}; 715 for (var key in hash) { 716 newHash[key] = func(hash[key], key); 717 } 718 return newHash; 719 } 720 function arrayToHash(a) { 721 var hash = {}; 722 for (var _i = 0, a_1 = a; _i < a_1.length; _i++) { 723 var item = a_1[_i]; 724 hash[item] = true; 725 } 726 return hash; 727 } 728 function buildHashFromArray(a, func) { 729 var hash = {}; 730 for (var i = 0; i < a.length; i += 1) { 731 var tuple = func(a[i], i); 732 hash[tuple[0]] = tuple[1];
733 } 734 return hash; 735 } 736 function hashValuesToArray(obj) { 737 var a = []; 738 for (var key in obj) { 739 a.push(obj[key]); 740 } 741 return a; 742 } 743 function isPropsEqual(obj0, obj1) { 744 if (obj0 === obj1) { 745 return true; 746 } 747 for (var key in obj0) { 748 if (hasOwnProperty.call(obj0, key)) { 749 if (!(key in obj1)) { 750 return false; 751 } 752 } 753 } 754 for (var key in obj1) { 755 if (hasOwnProperty.call(obj1, key)) { 756 if (obj0[key] !== obj1[key]) { 757 return false; 758 } 759 } 760 } 761 return true; 762 } 763 function getUnequalProps(obj0, obj1) { 764 var keys = []; 765 for (var key in obj0) { 766 if (hasOwnProperty.call(obj0, key)) { 767 if (!(key in obj1)) { 768 keys.push(key); 769 } 770 } 771 } 772 for (var key in obj1) { 773 if (hasOwnProperty.call(obj1, key)) { 774 if (obj0[key] !== obj1[key]) { 775 keys.push(key); 776 } 777 } 778 } 779 return keys; 780 } 781 function compareObjs(oldProps, newProps, equalityFuncs) { 782 if (equalityFuncs === void 0) { equalityFuncs = {}; } 783 if (oldProps === newProps) { 784 return true; 785 } 786 for (var key in newProps) { 787 if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) ; 788 else { 789 return false; 790 } 791 } 792 // check for props that were omitted in the new 793 for (var key in oldProps) { 794 if (!(key in newProps)) { 795 return false; 796 } 797 } 798 return true; 799 } 800 /* 801 assumed "true" equality for handler names like "onReceiveSomething" 802 */ 803 function isObjValsEqual(val0, val1, comparator) { 804 if (val0 === val1 || comparator === true) { 805 return true; 806 } 807 if (comparator) { 808 return comparator(val0, val1); 809 } 810 return false; 811 } 812 function collectFromHash(hash, startIndex, endIndex, step) { 813 if (startIndex === void 0) { startIndex = 0; } 814 if (step === void 0) { step = 1; } 815 var res = []; 816 if (endIndex == null) { 817 endIndex = Object.keys(hash).length; 818 } 819 for (var i = startIndex; i < endIndex; i += step) { 820 var val = hash[i]; 821 if (val !== undefined) { // will disregard undefined for sparse arrays 822 res.push(val); 823 } 824 } 825 return res; 826 } 827 828 function parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) { 829 for (var i = 0; i < recurringTypes.length; i += 1) { 830 var parsed = recurringTypes[i].parse(refined, dateEnv); 831 if (parsed) { 832 var allDay = refined.allDay; 833 if (allDay == null) { 834 allDay = defaultAllDay; 835 if (allDay == null) { 836 allDay = parsed.allDayGuess; 837 if (allDay == null) { 838 allDay = false; 839 } 840 } 841 } 842 return { 843 allDay: allDay, 844 duration: parsed.duration, 845 typeData: parsed.typeData, 846 typeId: i, 847 }; 848 } 849 } 850 return null; 851 } 852 function expandRecurring(eventStore, framingRange, context) { 853 var dateEnv = context.dateEnv, pluginHooks = context.pluginHooks, options = context.options; 854 var defs = eventStore.defs, instances = eventStore.instances; 855 // remove existing recurring instances 856 // TODO: bad. always expand events as a second step 857 instances = filterHash(instances, function (instance) { return !defs[instance.defId].recurringDef; }); 858 for (var defId in defs) { 859 var def = defs[defId]; 860 if (def.recurringDef) { 861 var duration = def.recurringDef.duration; 862 if (!duration) { 863 duration = def.allDay ? 864 options.defaultAllDayEventDuration : 865 options.defaultTimedEventDuration; 866 } 867 var starts = expandRecurringRanges(def, duration, framingRange, dateEnv, pluginHooks.recurringTypes); 868 for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) { 869 var start = starts_1[_i]; 870 var instance = createEventInstance(defId, { 871 start: start, 872 end: dateEnv.add(start, duration), 873 }); 874 instances[instance.instanceId] = instance; 875 } 876 } 877 } 878 return { defs: defs, instances: instances }; 879 } 880 /* 881 Event MUST have a recurringDef 882 */ 883 function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) { 884 var typeDef = recurringTypes[eventDef.recurringDef.typeId]; 885 var markers = typeDef.expand(eventDef.recurringDef.typeData, { 886 start: dateEnv.subtract(framingRange.start, duration), 887 end: framingRange.end, 888 }, dateEnv); 889 // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to 890 if (eventDef.allDay) { 891 markers = markers.map(startOfDay); 892 } 893 return markers; 894 } 895 896 var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
897 var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/; 898 // Parsing and Creation 899 function createDuration(input, unit) { 900 var _a; 901 if (typeof input === 'string') { 902 return parseString(input); 903 } 904 if (typeof input === 'object' && input) { // non-null object 905 return parseObject(input); 906 } 907 if (typeof input === 'number') { 908 return parseObject((_a = {}, _a[unit || 'milliseconds'] = input, _a)); 909 } 910 return null; 911 } 912 function parseString(s) { 913 var m = PARSE_RE.exec(s); 914 if (m) { 915 var sign = m[1] ? -1 : 1; 916 return { 917 years: 0, 918 months: 0, 919 days: sign * (m[2] ? parseInt(m[2], 10) : 0), 920 milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours 921 (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes 922 (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds 923 (m[6] ? parseInt(m[6], 10) : 0) // ms 924 ), 925 }; 926 } 927 return null; 928 } 929 function parseObject(obj) { 930 var duration = { 931 years: obj.years || obj.year || 0, 932 months: obj.months || obj.month || 0, 933 days: obj.days || obj.day || 0, 934 milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours 935 (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes 936 (obj.seconds || obj.second || 0) * 1000 + // seconds 937 (obj.milliseconds || obj.millisecond || obj.ms || 0), // ms 938 }; 939 var weeks = obj.weeks || obj.week; 940 if (weeks) { 941 duration.days += weeks * 7; 942 duration.specifiedWeeks = true; 943 } 944 return duration; 945 } 946 // Equality 947 function durationsEqual(d0, d1) { 948 return d0.years === d1.years && 949 d0.months === d1.months && 950 d0.days === d1.days && 951 d0.milliseconds === d1.milliseconds; 952 } 953 function asCleanDays(dur) { 954 if (!dur.years && !dur.months && !dur.milliseconds) { 955 return dur.days; 956 } 957 return 0; 958 } 959 // Simple Math 960 function addDurations(d0, d1) { 961 return { 962 years: d0.years + d1.years, 963 months: d0.months + d1.months, 964 days: d0.days + d1.days, 965 milliseconds: d0.milliseconds + d1.milliseconds, 966 }; 967 } 968 function subtractDurations(d1, d0) { 969 return { 970 years: d1.years - d0.years, 971 months: d1.months - d0.months, 972 days: d1.days - d0.days, 973 milliseconds: d1.milliseconds - d0.milliseconds, 974 }; 975 } 976 function multiplyDuration(d, n) { 977 return { 978 years: d.years * n, 979 months: d.months * n, 980 days: d.days * n, 981 milliseconds: d.milliseconds * n, 982 }; 983 } 984 // Conversions 985 // "Rough" because they are based on average-case Gregorian months/years 986 function asRoughYears(dur) { 987 return asRoughDays(dur) / 365; 988 } 989 function asRoughMonths(dur) { 990 return asRoughDays(dur) / 30; 991 } 992 function asRoughDays(dur) { 993 return asRoughMs(dur) / 864e5; 994 } 995 function asRoughMinutes(dur) { 996 return asRoughMs(dur) / (1000 * 60); 997 } 998 function asRoughSeconds(dur) { 999 return asRoughMs(dur) / 1000; 1000 } 1001 function asRoughMs(dur) { 1002 return dur.years * (365 * 864e5) + 1003 dur.months * (30 * 864e5) + 1004 dur.days * 864e5 + 1005 dur.milliseconds; 1006 } 1007 // Advanced Math 1008 function wholeDivideDurations(numerator, denominator) { 1009 var res = null; 1010 for (var i = 0; i < INTERNAL_UNITS.length; i += 1) { 1011 var unit = INTERNAL_UNITS[i]; 1012 if (denominator[unit]) { 1013 var localRes = numerator[unit] / denominator[unit]; 1014 if (!isInt(localRes) || (res !== null && res !== localRes)) { 1015 return null; 1016 } 1017 res = localRes; 1018 } 1019 else if (numerator[unit]) { 1020 // needs to divide by something but can't! 1021 return null; 1022 } 1023 } 1024 return res; 1025 } 1026 function greatestDurationDenominator(dur) { 1027 var ms = dur.milliseconds; 1028 if (ms) { 1029 if (ms % 1000 !== 0) { 1030 return { unit: 'millisecond', value: ms }; 1031 } 1032 if (ms % (1000 * 60) !== 0) { 1033 return { unit: 'second', value: ms / 1000 }; 1034 } 1035 if (ms % (1000 * 60 * 60) !== 0) { 1036 return { unit: 'minute', value: ms / (1000 * 60) }; 1037 } 1038 if (ms) { 1039 return { unit: 'hour', value: ms / (1000 * 60 * 60) }; 1040 } 1041 } 1042 if (dur.days) { 1043 if (dur.specifiedWeeks && dur.days % 7 === 0) { 1044 return { unit: 'week', value: dur.days / 7 }; 1045 } 1046 return { unit: 'day', value: dur.days }; 1047 } 1048 if (dur.months) { 1049 return { unit: 'month', value: dur.months }; 1050 } 1051 if (dur.years) { 1052 return { unit: 'year', value: dur.years }; 1053 } 1054 return { unit: 'millisecond', value: 0 }; 1055 } 1056 1057 // timeZoneOffset is in minutes 1058 function buildIsoString(marker, timeZoneOffset, stripZeroTime) { 1059 if (stripZeroTime === void 0) { stripZeroTime = false; } 1060 var s = marker.toISOString(); 1061 s = s.replace('.000', ''); 1062 if (stripZeroTime) { 1063 s = s.replace('T00:00:00Z', ''); 1064 } 1065 if (s.length > 10) { // time part wasn't stripped, can add timezone info 1066 if (timeZoneOffset == null) { 1067 s = s.replace('Z', ''); 1068 } 1069 else if (timeZoneOffset !== 0) { 1070 s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true)); 1071 } 1072 // otherwise, its UTC-0 and we want to keep the Z 1073 } 1074 return s; 1075 } 1076 // formats the date, but with no time part 1077 // TODO: somehow merge with buildIsoString and stripZeroTime 1078 // TODO: rename. omit "string" 1079 function formatDayString(marker) { 1080 return marker.toISOString().replace(/T.*$/, ''); 1081 } 1082 // TODO: use Date::toISOString and use everything after the T? 1083 function formatIsoTimeString(marker) { 1084 return padStart(marker.getUTCHours(), 2) + ':' + 1085 padStart(marker.getUTCMinutes(), 2) + ':' + 1086 padStart(marker.getUTCSeconds(), 2); 1087 } 1088 function formatTimeZoneOffset(minutes, doIso) { 1089 if (doIso === void 0) { doIso = false; } 1090 var sign = minutes < 0 ? '-' : '+'; 1091 var abs = Math.abs(minutes); 1092 var hours = Math.floor(abs / 60); 1093 var mins = Math.round(abs % 60); 1094 if (doIso) { 1095 return sign + padStart(hours, 2) + ":" + padStart(mins, 2); 1096 } 1097 return "GMT" + sign + hours + (mins ? ":" + padStart(mins, 2) : ''); 1098 } 1099 1100 // TODO: new util arrayify? 1101 function removeExact(array, exactVal) { 1102 var removeCnt = 0; 1103 var i = 0; 1104 while (i < array.length) { 1105 if (array[i] === exactVal) { 1106 array.splice(i, 1); 1107 removeCnt += 1; 1108 } 1109 else { 1110 i += 1; 1111 } 1112 } 1113 return removeCnt; 1114 } 1115 function isArraysEqual(a0, a1, equalityFunc) { 1116 if (a0 === a1) { 1117 return true; 1118 } 1119 var len = a0.length; 1120 var i; 1121 if (len !== a1.length) { // not array? or not same length? 1122 return false; 1123 } 1124 for (i = 0; i < len; i += 1) { 1125 if (!(equalityFunc ? equalityFunc(a0[i], a1[i]) : a0[i] === a1[i])) { 1126 return false; 1127 } 1128 } 1129 return true; 1130 } 1131 1132 function memoize(workerFunc, resEquality, teardownFunc) { 1133 var currentArgs; 1134 var currentRes; 1135 return function () { 1136 var newArgs = []; 1137 for (var _i = 0; _i < arguments.length; _i++) { 1138 newArgs[_i] = arguments[_i]; 1139 } 1140 if (!currentArgs) {
1141 currentRes = workerFunc.apply(this, newArgs); 1142 } 1143 else if (!isArraysEqual(currentArgs, newArgs)) { 1144 if (teardownFunc) { 1145 teardownFunc(currentRes); 1146 } 1147 var res = workerFunc.apply(this, newArgs); 1148 if (!resEquality || !resEquality(res, currentRes)) { 1149 currentRes = res; 1150 } 1151 } 1152 currentArgs = newArgs; 1153 return currentRes; 1154 }; 1155 } 1156 function memoizeObjArg(workerFunc, resEquality, teardownFunc) { 1157 var _this = this; 1158 var currentArg; 1159 var currentRes; 1160 return function (newArg) { 1161 if (!currentArg) { 1162 currentRes = workerFunc.call(_this, newArg); 1163 } 1164 else if (!isPropsEqual(currentArg, newArg)) { 1165 if (teardownFunc) { 1166 teardownFunc(currentRes); 1167 } 1168 var res = workerFunc.call(_this, newArg); 1169 if (!resEquality || !resEquality(res, currentRes)) { 1170 currentRes = res; 1171 } 1172 } 1173 currentArg = newArg; 1174 return currentRes; 1175 }; 1176 } 1177 function memoizeArraylike(// used at all? 1178 workerFunc, resEquality, teardownFunc) { 1179 var _this = this; 1180 var currentArgSets = []; 1181 var currentResults = []; 1182 return function (newArgSets) { 1183 var currentLen = currentArgSets.length; 1184 var newLen = newArgSets.length; 1185 var i = 0; 1186 for (; i < currentLen; i += 1) { 1187 if (!newArgSets[i]) { // one of the old sets no longer exists 1188 if (teardownFunc) { 1189 teardownFunc(currentResults[i]); 1190 } 1191 } 1192 else if (!isArraysEqual(currentArgSets[i], newArgSets[i])) { 1193 if (teardownFunc) { 1194 teardownFunc(currentResults[i]); 1195 } 1196 var res = workerFunc.apply(_this, newArgSets[i]); 1197 if (!resEquality || !resEquality(res, currentResults[i])) { 1198 currentResults[i] = res; 1199 } 1200 } 1201 } 1202 for (; i < newLen; i += 1) { 1203 currentResults[i] = workerFunc.apply(_this, newArgSets[i]); 1204 } 1205 currentArgSets = newArgSets; 1206 currentResults.splice(newLen); // remove excess 1207 return currentResults; 1208 }; 1209 } 1210 function memoizeHashlike(// used? 1211 workerFunc, resEquality, teardownFunc) { 1212 var _this = this; 1213 var currentArgHash = {}; 1214 var currentResHash = {}; 1215 return function (newArgHash) { 1216 var newResHash = {}; 1217 for (var key in newArgHash) { 1218 if (!currentResHash[key]) { 1219 newResHash[key] = workerFunc.apply(_this, newArgHash[key]); 1220 } 1221 else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) { 1222 if (teardownFunc) { 1223 teardownFunc(currentResHash[key]); 1224 } 1225 var res = workerFunc.apply(_this, newArgHash[key]); 1226 newResHash[key] = (resEquality && resEquality(res, currentResHash[key])) 1227 ? currentResHash[key] 1228 : res; 1229 } 1230 else { 1231 newResHash[key] = currentResHash[key]; 1232 } 1233 } 1234 currentArgHash = newArgHash; 1235 currentResHash = newResHash; 1236 return newResHash; 1237 }; 1238 } 1239 1240 var EXTENDED_SETTINGS_AND_SEVERITIES = { 1241 week: 3, 1242 separator: 0, 1243 omitZeroMinute: 0, 1244 meridiem: 0, 1245 omitCommas: 0, 1246 }; 1247 var STANDARD_DATE_PROP_SEVERITIES = { 1248 timeZoneName: 7, 1249 era: 6, 1250 year: 5, 1251 month: 4, 1252 day: 2, 1253 weekday: 2, 1254 hour: 1, 1255 minute: 1, 1256 second: 1, 1257 }; 1258 var MERIDIEM_RE = /\s*([ap])\.?m\.?/i;
1258 // eats up leading spaces too 1259 var COMMA_RE = /,/g; // we need re for globalness 1260 var MULTI_SPACE_RE = /\s+/g; 1261 var LTR_RE = /\u200e/g; // control character 1262 var UTC_RE = /UTC|GMT/; 1263 var NativeFormatter = /** @class */ (function () { 1264 function NativeFormatter(formatSettings) { 1265 var standardDateProps = {}; 1266 var extendedSettings = {}; 1267 var severity = 0; 1268 for (var name_1 in formatSettings) { 1269 if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) { 1270 extendedSettings[name_1] = formatSettings[name_1]; 1271 severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity); 1272 } 1273 else { 1274 standardDateProps[name_1] = formatSettings[name_1]; 1275 if (name_1 in STANDARD_DATE_PROP_SEVERITIES) { // TODO: what about hour12? no severity 1276 severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity); 1277 } 1278 } 1279 } 1280 this.standardDateProps = standardDateProps; 1281 this.extendedSettings = extendedSettings; 1282 this.severity = severity; 1283 this.buildFormattingFunc = memoize(buildFormattingFunc); 1284 } 1285 NativeFormatter.prototype.format = function (date, context) { 1286 return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date); 1287 }; 1288 NativeFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) { 1289 var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings; 1290 var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem); 1291 if (!diffSeverity) { 1292 return this.format(start, context); 1293 } 1294 var biggestUnitForPartial = diffSeverity; 1295 if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time 1296 (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') && 1297 (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') && 1298 (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) { 1299 biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time 1300 } 1301 var full0 = this.format(start, context); 1302 var full1 = this.format(end, context); 1303 if (full0 === full1) { 1304 return full0; 1305 } 1306 var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial); 1307 var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context); 1308 var partial0 = partialFormattingFunc(start); 1309 var partial1 = partialFormattingFunc(end); 1310 var insertion = findCommonInsertion(full0, partial0, full1, partial1); 1311 var separator = extendedSettings.separator || betterDefaultSeparator || context.defaultSeparator || ''; 1312 if (insertion) { 1313 return insertion.before + partial0 + separator + partial1 + insertion.after; 1314 } 1315 return full0 + separator + full1; 1316 }; 1317 NativeFormatter.prototype.getLargestUnit = function () { 1318 switch (this.severity) { 1319 case 7: 1320 case 6: 1321 case 5: 1322 return 'year'; 1323 case 4: 1324 return 'month'; 1325 case 3: 1326 return 'week'; 1327 case 2: 1328 return 'day'; 1329 default: 1330 return 'time'; // really? 1331 } 1332 }; 1333 return NativeFormatter; 1334 }()); 1335 function buildFormattingFunc(standardDateProps, extendedSettings, context) { 1336 var standardDatePropCnt = Object.keys(standardDateProps).length; 1337 if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') { 1338 return function (date) { return (formatTimeZoneOffset(date.timeZoneOffset)); }; 1339 } 1340 if (standardDatePropCnt === 0 && extendedSettings.week) { 1341 return function (date) { return (formatWeekNumber(context.computeWeekNumber(date.marker), context.weekText, context.weekTextLong, context.locale, extendedSettings.week)); }; 1342 } 1343 return buildNativeFormattingFunc(standardDateProps, extendedSettings, context); 1344 } 1345 function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) { 1346 standardDateProps = __assign({}, standardDateProps); // copy 1347 extendedSettings = __assign({}, extendedSettings); // copy 1348 sanitizeSettings(standardDateProps, extendedSettings); 1349 standardDateProps.timeZone = 'UTC';
1349 // we leverage the only guaranteed timeZone for our UTC markers 1350 var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps); 1351 var zeroFormat; // needed? 1352 if (extendedSettings.omitZeroMinute) { 1353 var zeroProps = __assign({}, standardDateProps); 1354 delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings 1355 zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps); 1356 } 1357 return function (date) { 1358 var marker = date.marker; 1359 var format; 1360 if (zeroFormat && !marker.getUTCMinutes()) { 1361 format = zeroFormat; 1362 } 1363 else { 1364 format = normalFormat; 1365 } 1366 var s = format.format(marker); 1367 return postProcess(s, date, standardDateProps, extendedSettings, context); 1368 }; 1369 } 1370 function sanitizeSettings(standardDateProps, extendedSettings) { 1371 // deal with a browser inconsistency where formatting the timezone 1372 // requires that the hour/minute be present. 1373 if (standardDateProps.timeZoneName) { 1374 if (!standardDateProps.hour) { 1375 standardDateProps.hour = '2-digit'; 1376 } 1377 if (!standardDateProps.minute) { 1378 standardDateProps.minute = '2-digit'; 1379 } 1380 } 1381 // only support short timezone names 1382 if (standardDateProps.timeZoneName === 'long') { 1383 standardDateProps.timeZoneName = 'short'; 1384 } 1385 // if requesting to display seconds, MUST display minutes 1386 if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) { 1387 delete extendedSettings.omitZeroMinute; 1388 } 1389 } 1390 function postProcess(s, date, standardDateProps, extendedSettings, context) { 1391 s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes 1392 if (standardDateProps.timeZoneName === 'short') { 1393 s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ? 1394 'UTC' : // important to normalize for IE, which does "GMT" 1395 formatTimeZoneOffset(date.timeZoneOffset)); 1396 } 1397 if (extendedSettings.omitCommas) { 1398 s = s.replace(COMMA_RE, '').trim(); 1399 } 1400 if (extendedSettings.omitZeroMinute) { 1401 s = s.replace(':00', ''); // zeroFormat doesn't always achieve this 1402 } 1403 // ^ do anything that might create adjacent spaces before this point, 1404 // because MERIDIEM_RE likes to eat up loading spaces 1405 if (extendedSettings.meridiem === false) { 1406 s = s.replace(MERIDIEM_RE, '').trim(); 1407 } 1408 else if (extendedSettings.meridiem === 'narrow') { // a/p 1409 s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase(); }); 1410 } 1411 else if (extendedSettings.meridiem === 'short') { // am/pm 1412 s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase() + "m"; }); 1413 } 1414 else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase 1415 s = s.replace(MERIDIEM_RE, function (m0) { return m0.toLocaleLowerCase(); }); 1416 } 1417 s = s.replace(MULTI_SPACE_RE, ' '); 1418 s = s.trim(); 1419 return s; 1420 } 1421 function injectTzoStr(s, tzoStr) { 1422 var replaced = false; 1423 s = s.replace(UTC_RE, function () { 1424 replaced = true; 1425 return tzoStr; 1426 }); 1427 // IE11 doesn't include UTC/GMT in the original string, so append to end 1428 if (!replaced) { 1429 s += " " + tzoStr; 1430 } 1431 return s; 1432 } 1433 function formatWeekNumber(num, weekText, weekTextLong, locale, display) { 1434 var parts = []; 1435 if (display === 'long') { 1436 parts.push(weekTextLong); 1437 } 1438 else if (display === 'short' || display === 'narrow') { 1439 parts.push(weekText); 1440 } 1441 if (display === 'long' || display === 'short') { 1442 parts.push(' '); 1443 } 1444 parts.push(locale.simpleNumberFormat.format(num)); 1445 if (locale.options.direction === 'rtl') { // TODO: use control characters instead? 1446 parts.reverse(); 1447 } 1448 return parts.join(''); 1449 } 1450 // Range Formatting Utils 1451 // 0 = exactly the same 1452 // 1 = different by time 1453 // and bigger 1454 function computeMarkerDiffSeverity(d0, d1, ca) { 1455 if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) { 1456 return 5; 1457 } 1458 if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) { 1459 return 4; 1460 } 1461 if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) { 1462 return 2; 1463 } 1464 if (timeAsMs(d0) !== timeAsMs(d1)) { 1465 return 1; 1466 } 1467 return 0; 1468 } 1469 function computePartialFormattingOptions(options, biggestUnit) { 1470 var partialOptions = {}; 1471 for (var name_2 in options) { 1472 if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone) 1473 STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) { 1474 partialOptions[name_2] = options[name_2]; 1475 } 1476 } 1477 return partialOptions; 1478 } 1479 function findCommonInsertion(full0, partial0, full1, partial1) { 1480 var i0 = 0; 1481 while (i0 < full0.length) { 1482 var found0 = full0.indexOf(partial0, i0); 1483 if (found0 === -1) { 1484 break; 1485 } 1486 var before0 = full0.substr(0, found0); 1487 i0 = found0 + partial0.length; 1488 var after0 = full0.substr(i0); 1489 var i1 = 0; 1490 while (i1 < full1.length) { 1491 var found1 = full1.indexOf(partial1, i1);
1492 if (found1 === -1) { 1493 break; 1494 } 1495 var before1 = full1.substr(0, found1); 1496 i1 = found1 + partial1.length; 1497 var after1 = full1.substr(i1); 1498 if (before0 === before1 && after0 === after1) { 1499 return { 1500 before: before0, 1501 after: after0, 1502 }; 1503 } 1504 } 1505 } 1506 return null; 1507 } 1508 1509 function expandZonedMarker(dateInfo, calendarSystem) { 1510 var a = calendarSystem.markerToArray(dateInfo.marker); 1511 return { 1512 marker: dateInfo.marker, 1513 timeZoneOffset: dateInfo.timeZoneOffset, 1514 array: a, 1515 year: a[0], 1516 month: a[1], 1517 day: a[2], 1518 hour: a[3], 1519 minute: a[4], 1520 second: a[5], 1521 millisecond: a[6], 1522 }; 1523 } 1524 1525 function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) { 1526 var startInfo = expandZonedMarker(start, context.calendarSystem); 1527 var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null; 1528 return { 1529 date: startInfo, 1530 start: startInfo, 1531 end: endInfo, 1532 timeZone: context.timeZone, 1533 localeCodes: context.locale.codes, 1534 defaultSeparator: betterDefaultSeparator || context.defaultSeparator, 1535 }; 1536 } 1537 1538 /* 1539 TODO: fix the terminology of "formatter" vs "formatting func" 1540 */ 1541 /* 1542 At the time of instantiation, this object does not know which cmd-formatting system it will use. 1543 It receives this at the time of formatting, as a setting. 1544 */ 1545 var CmdFormatter = /** @class */ (function () { 1546 function CmdFormatter(cmdStr) { 1547 this.cmdStr = cmdStr; 1548 } 1549 CmdFormatter.prototype.format = function (date, context, betterDefaultSeparator) { 1550 return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator)); 1551 }; 1552 CmdFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) { 1553 return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator)); 1554 }; 1555 return CmdFormatter; 1556 }()); 1557 1558 var FuncFormatter = /** @class */ (function () { 1559 function FuncFormatter(func) { 1560 this.func = func; 1561 } 1562 FuncFormatter.prototype.format = function (date, context, betterDefaultSeparator) { 1563 return this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator)); 1564 }; 1565 FuncFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) { 1566 return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator)); 1567 }; 1568 return FuncFormatter; 1569 }()); 1570 1571 function createFormatter(input) { 1572 if (typeof input === 'object' && input) { // non-null object 1573 return new NativeFormatter(input); 1574 } 1575 if (typeof input === 'string') { 1576 return new CmdFormatter(input); 1577 } 1578 if (typeof input === 'function') { 1579 return new FuncFormatter(input); 1580 } 1581 return null; 1582 } 1583 1584 // base options 1585 // ------------ 1586 var BASE_OPTION_REFINERS = { 1587 navLinkDayClick: identity, 1588 navLinkWeekClick: identity, 1589 duration: createDuration, 1590 bootstrapFontAwesome: identity, 1591 buttonIcons: identity, 1592 customButtons: identity, 1593 defaultAllDayEventDuration: createDuration, 1594 defaultTimedEventDuration: createDuration, 1595 nextDayThreshold: createDuration, 1596 scrollTime: createDuration, 1597 scrollTimeReset: Boolean, 1598 slotMinTime: createDuration, 1599 slotMaxTime: createDuration, 1600 dayPopoverFormat: createFormatter, 1601 slotDuration: createDuration, 1602 snapDuration: createDuration, 1603 headerToolbar: identity, 1604 footerToolbar: identity, 1605 defaultRangeSeparator: String, 1606 titleRangeSeparator: String, 1607 forceEventDuration: Boolean, 1608 dayHeaders: Boolean, 1609 dayHeaderFormat: createFormatter, 1610 dayHeaderClassNames: identity, 1611 dayHeaderContent: identity, 1612 dayHeaderDidMount: identity, 1613 dayHeaderWillUnmount: identity, 1614 dayCellClassNames: identity, 1615 dayCellContent: identity, 1616 dayCellDidMount: identity, 1617 dayCellWillUnmount: identity, 1618 initialView: String, 1619 aspectRatio: Number, 1620 weekends: Boolean, 1621 weekNumberCalculation: identity, 1622 weekNumbers: Boolean, 1623 weekNumberClassNames: identity, 1624 weekNumberContent: identity, 1625 weekNumberDidMount: identity, 1626 weekNumberWillUnmount: identity, 1627 editable: Boolean, 1628 viewClassNames: identity, 1629 viewDidMount: identity, 1630 viewWillUnmount: identity, 1631 nowIndicator: Boolean, 1632 nowIndicatorClassNames: identity, 1633 nowIndicatorContent: identity, 1634 nowIndicatorDidMount: identity, 1635 nowIndicatorWillUnmount: identity, 1636 showNonCurrentDates: Boolean, 1637 lazyFetching: Boolean, 1638 startParam: String, 1639 endParam: String, 1640 timeZoneParam: String, 1641 timeZone: String, 1642 locales: identity, 1643 locale: identity, 1644 themeSystem: String, 1645 dragRevertDuration: Number, 1646 dragScroll: Boolean, 1647 allDayMaintainDuration: Boolean, 1648 unselectAuto: Boolean, 1649 dropAccept: identity, 1650 eventOrder: parseFieldSpecs, 1651 eventOrderStrict: Boolean, 1652 handleWindowResize: Boolean, 1653 windowResizeDelay: Number, 1654 longPressDelay: Number, 1655 eventDragMinDistance: Number, 1656 expandRows: Boolean, 1657 height: identity, 1658 contentHeight: identity, 1659 direction: String, 1660 weekNumberFormat: createFormatter, 1661 eventResizableFromStart: Boolean, 1662 displayEventTime: Boolean, 1663 displayEventEnd: Boolean, 1664 weekText: String, 1665 weekTextLong: String, 1666 progressiveEventRendering: Boolean, 1667 businessHours: identity, 1668 initialDate: identity, 1669 now: identity, 1670 eventDataTransform: identity, 1671 stickyHeaderDates: identity, 1672 stickyFooterScrollbar: identity, 1673 viewHeight: identity, 1674 defaultAllDay: Boolean, 1675 eventSourceFailure: identity, 1676 eventSourceSuccess: identity, 1677 eventDisplay: String, 1678 eventStartEditable: Boolean, 1679 eventDurationEditable: Boolean, 1680 eventOverlap: identity, 1681 eventConstraint: identity, 1682 eventAllow: identity,
1683 eventBackgroundColor: String, 1684 eventBorderColor: String, 1685 eventTextColor: String, 1686 eventColor: String, 1687 eventClassNames: identity, 1688 eventContent: identity, 1689 eventDidMount: identity, 1690 eventWillUnmount: identity, 1691 selectConstraint: identity, 1692 selectOverlap: identity, 1693 selectAllow: identity, 1694 droppable: Boolean, 1695 unselectCancel: String, 1696 slotLabelFormat: identity, 1697 slotLaneClassNames: identity, 1698 slotLaneContent: identity, 1699 slotLaneDidMount: identity, 1700 slotLaneWillUnmount: identity, 1701 slotLabelClassNames: identity, 1702 slotLabelContent: identity, 1703 slotLabelDidMount: identity, 1704 slotLabelWillUnmount: identity, 1705 dayMaxEvents: identity, 1706 dayMaxEventRows: identity, 1707 dayMinWidth: Number, 1708 slotLabelInterval: createDuration, 1709 allDayText: String, 1710 allDayClassNames: identity, 1711 allDayContent: identity, 1712 allDayDidMount: identity, 1713 allDayWillUnmount: identity, 1714 slotMinWidth: Number, 1715 navLinks: Boolean, 1716 eventTimeFormat: createFormatter, 1717 rerenderDelay: Number, 1718 moreLinkText: identity, 1719 moreLinkHint: identity, 1720 selectMinDistance: Number, 1721 selectable: Boolean, 1722 selectLongPressDelay: Number, 1723 eventLongPressDelay: Number, 1724 selectMirror: Boolean, 1725 eventMaxStack: Number, 1726 eventMinHeight: Number, 1727 eventMinWidth: Number, 1728 eventShortHeight: Number, 1729 slotEventOverlap: Boolean, 1730 plugins: identity, 1731 firstDay: Number, 1732 dayCount: Number, 1733 dateAlignment: String, 1734 dateIncrement: createDuration, 1735 hiddenDays: identity, 1736 monthMode: Boolean, 1737 fixedWeekCount: Boolean, 1738 validRange: identity, 1739 visibleRange: identity, 1740 titleFormat: identity, 1741 eventInteractive: Boolean, 1742 // only used by list-view, but languages define the value, so we need it in base options 1743 noEventsText: String, 1744 viewHint: identity, 1745 navLinkHint: identity, 1746 closeHint: String, 1747 timeHint: String, 1748 eventHint: String, 1749 moreLinkClick: identity, 1750 moreLinkClassNames: identity, 1751 moreLinkContent: identity, 1752 moreLinkDidMount: identity, 1753 moreLinkWillUnmount: identity, 1754 }; 1755 // do NOT give a type here. need `typeof BASE_OPTION_DEFAULTS` to give real results. 1756 // raw values. 1757 var BASE_OPTION_DEFAULTS = { 1758 eventDisplay: 'auto', 1759 defaultRangeSeparator: ' - ', 1760 titleRangeSeparator: ' \u2013 ', 1761 defaultTimedEventDuration: '01:00:00', 1762 defaultAllDayEventDuration: { day: 1 }, 1763 forceEventDuration: false, 1764 nextDayThreshold: '00:00:00', 1765 dayHeaders: true, 1766 initialView: '', 1767 aspectRatio: 1.35, 1768 headerToolbar: { 1769 start: 'title', 1770 center: '', 1771 end: 'today prev,next', 1772 }, 1773 weekends: true, 1774 weekNumbers: false, 1775 weekNumberCalculation: 'local', 1776 editable: false, 1777 nowIndicator: false, 1778 scrollTime: '06:00:00', 1779 scrollTimeReset: true, 1780 slotMinTime: '00:00:00', 1781 slotMaxTime: '24:00:00', 1782 showNonCurrentDates: true, 1783 lazyFetching: true, 1784 startParam: 'start', 1785 endParam: 'end', 1786 timeZoneParam: 'timeZone', 1787 timeZone: 'local', 1788 locales: [], 1789 locale: '', 1790 themeSystem: 'standard', 1791 dragRevertDuration: 500, 1792 dragScroll: true, 1793 allDayMaintainDuration: false, 1794 unselectAuto: true, 1795 dropAccept: '*', 1796 eventOrder: 'start,-duration,allDay,title', 1797 dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' }, 1798 handleWindowResize: true, 1799 windowResizeDelay: 100, 1800 longPressDelay: 1000, 1801 eventDragMinDistance: 5, 1802 expandRows: false, 1803 navLinks: false, 1804 selectable: false, 1805 eventMinHeight: 15, 1806 eventMinWidth: 30, 1807 eventShortHeight: 30, 1808 }; 1809 // calendar listeners 1810 // ------------------ 1811 var CALENDAR_LISTENER_REFINERS = { 1812 datesSet: identity, 1813 eventsSet: identity, 1814 eventAdd: identity, 1815 eventChange: identity, 1816 eventRemove: identity, 1817 windowResize: identity, 1818 eventClick: identity, 1819 eventMouseEnter: identity, 1820 eventMouseLeave: identity, 1821 select: identity, 1822 unselect: identity, 1823 loading: identity, 1824 // internal 1825 _unmount: identity, 1826 _beforeprint: identity, 1827 _afterprint: identity, 1828 _noEventDrop: identity, 1829 _noEventResize: identity, 1830 _resize: identity, 1831 _scrollRequest: identity, 1832 }; 1833 // calendar-specific options 1834 // ------------------------- 1835 var CALENDAR_OPTION_REFINERS = { 1836 buttonText: identity, 1837 buttonHints: identity, 1838 views: identity, 1839 plugins: identity, 1840 initialEvents: identity,
1841 events: identity, 1842 eventSources: identity, 1843 }; 1844 var COMPLEX_OPTION_COMPARATORS = { 1845 headerToolbar: isBoolComplexEqual, 1846 footerToolbar: isBoolComplexEqual, 1847 buttonText: isBoolComplexEqual, 1848 buttonHints: isBoolComplexEqual, 1849 buttonIcons: isBoolComplexEqual, 1850 }; 1851 function isBoolComplexEqual(a, b) { 1852 if (typeof a === 'object' && typeof b === 'object' && a && b) { // both non-null objects 1853 return isPropsEqual(a, b); 1854 } 1855 return a === b; 1856 } 1857 // view-specific options 1858 // --------------------- 1859 var VIEW_OPTION_REFINERS = { 1860 type: String, 1861 component: identity, 1862 buttonText: String, 1863 buttonTextKey: String, 1864 dateProfileGeneratorClass: identity, 1865 usesMinMaxTime: Boolean, 1866 classNames: identity, 1867 content: identity, 1868 didMount: identity, 1869 willUnmount: identity, 1870 }; 1871 // util funcs 1872 // ---------------------------------------------------------------------------------------------------- 1873 function mergeRawOptions(optionSets) { 1874 return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS); 1875 } 1876 function refineProps(input, refiners) { 1877 var refined = {}; 1878 var extra = {}; 1879 for (var propName in refiners) { 1880 if (propName in input) { 1881 refined[propName] = refiners[propName](input[propName]); 1882 } 1883 } 1884 for (var propName in input) { 1885 if (!(propName in refiners)) { 1886 extra[propName] = input[propName]; 1887 } 1888 } 1889 return { refined: refined, extra: extra }; 1890 } 1891 function identity(raw) { 1892 return raw; 1893 } 1894 1895 function parseEvents(rawEvents, eventSource, context, allowOpenRange) { 1896 var eventStore = createEmptyEventStore(); 1897 var eventRefiners = buildEventRefiners(context); 1898 for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) { 1899 var rawEvent = rawEvents_1[_i]; 1900 var tuple = parseEvent(rawEvent, eventSource, context, allowOpenRange, eventRefiners); 1901 if (tuple) { 1902 eventTupleToStore(tuple, eventStore); 1903 } 1904 } 1905 return eventStore; 1906 } 1907 function eventTupleToStore(tuple, eventStore) { 1908 if (eventStore === void 0) { eventStore = createEmptyEventStore(); } 1909 eventStore.defs[tuple.def.defId] = tuple.def; 1910 if (tuple.instance) { 1911 eventStore.instances[tuple.instance.instanceId] = tuple.instance; 1912 } 1913 return eventStore; 1914 } 1915 // retrieves events that have the same groupId as the instance specified by `instanceId` 1916 // or they are the same as the instance. 1917 // why might instanceId not be in the store? an event from another calendar? 1918 function getRelevantEvents(eventStore, instanceId) { 1919 var instance = eventStore.instances[instanceId]; 1920 if (instance) { 1921 var def_1 = eventStore.defs[instance.defId]; 1922 // get events/instances with same group 1923 var newStore = filterEventStoreDefs(eventStore, function (lookDef) { return isEventDefsGrouped(def_1, lookDef); }); 1924 // add the original 1925 // TODO: wish we could use eventTupleToStore or something like it 1926 newStore.defs[def_1.defId] = def_1; 1927 newStore.instances[instance.instanceId] = instance; 1928 return newStore; 1929 } 1930 return createEmptyEventStore(); 1931 } 1932 function isEventDefsGrouped(def0, def1) { 1933 return Boolean(def0.groupId && def0.groupId === def1.groupId); 1934 } 1935 function createEmptyEventStore() { 1936 return { defs: {}, instances: {} }; 1937 } 1938 function mergeEventStores(store0, store1) { 1939 return { 1940 defs: __assign(__assign({}, store0.defs), store1.defs), 1941 instances: __assign(__assign({}, store0.instances), store1.instances), 1942 }; 1943 } 1944 function filterEventStoreDefs(eventStore, filterFunc) { 1945 var defs = filterHash(eventStore.defs, filterFunc); 1946 var instances = filterHash(eventStore.instances, function (instance) { return (defs[instance.defId] // still exists?
vendor: 4,371 bytes, lines 1947-2054
1947 ); }); 1948 return { defs: defs, instances: instances }; 1949 } 1950 function excludeSubEventStore(master, sub) { 1951 var defs = master.defs, instances = master.instances; 1952 var filteredDefs = {}; 1953 var filteredInstances = {}; 1954 for (var defId in defs) { 1955 if (!sub.defs[defId]) { // not explicitly excluded 1956 filteredDefs[defId] = defs[defId]; 1957 } 1958 } 1959 for (var instanceId in instances) { 1960 if (!sub.instances[instanceId] && // not explicitly excluded 1961 filteredDefs[instances[instanceId].defId] // def wasn't filtered away 1962 ) { 1963 filteredInstances[instanceId] = instances[instanceId]; 1964 } 1965 } 1966 return { 1967 defs: filteredDefs, 1968 instances: filteredInstances, 1969 }; 1970 } 1971 1972 function normalizeConstraint(input, context) { 1973 if (Array.isArray(input)) { 1974 return parseEvents(input, null, context, true); // allowOpenRange=true 1975 } 1976 if (typeof input === 'object' && input) { // non-null object 1977 return parseEvents([input], null, context, true); // allowOpenRange=true 1978 } 1979 if (input != null) { 1980 return String(input); 1981 } 1982 return null; 1983 } 1984 1985 function parseClassNames(raw) { 1986 if (Array.isArray(raw)) { 1987 return raw; 1988 } 1989 if (typeof raw === 'string') { 1990 return raw.split(/\s+/); 1991 } 1992 return []; 1993 } 1994 1995 // TODO: better called "EventSettings" or "EventConfig" 1996 // TODO: move this file into structs 1997 // TODO: separate constraint/overlap/allow, because selection uses only that, not other props 1998 var EVENT_UI_REFINERS = { 1999 display: String, 2000 editable: Boolean, 2001 startEditable: Boolean, 2002 durationEditable: Boolean, 2003 constraint: identity, 2004 overlap: identity, 2005 allow: identity, 2006 className: parseClassNames, 2007 classNames: parseClassNames, 2008 color: String, 2009 backgroundColor: String, 2010 borderColor: String, 2011 textColor: String, 2012 }; 2013 var EMPTY_EVENT_UI = { 2014 display: null, 2015 startEditable: null, 2016 durationEditable: null, 2017 constraints: [], 2018 overlap: null, 2019 allows: [], 2020 backgroundColor: '', 2021 borderColor: '', 2022 textColor: '', 2023 classNames: [], 2024 }; 2025 function createEventUi(refined, context) { 2026 var constraint = normalizeConstraint(refined.constraint, context); 2027 return { 2028 display: refined.display || null, 2029 startEditable: refined.startEditable != null ? refined.startEditable : refined.editable, 2030 durationEditable: refined.durationEditable != null ? refined.durationEditable : refined.editable, 2031 constraints: constraint != null ? [constraint] : [], 2032 overlap: refined.overlap != null ? refined.overlap : null, 2033 allows: refined.allow != null ? [refined.allow] : [], 2034 backgroundColor: refined.backgroundColor || refined.color || '', 2035 borderColor: refined.borderColor || refined.color || '', 2036 textColor: refined.textColor || '', 2037 classNames: (refined.className || []).concat(refined.classNames || []), // join singular and plural 2038 }; 2039 } 2040 // TODO: prevent against problems with <2 args! 2041 function combineEventUis(uis) { 2042 return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI); 2043 } 2044 function combineTwoEventUis(item0, item1) { 2045 return { 2046 display: item1.display != null ? item1.display : item0.display, 2047 startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable, 2048 durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable, 2049 constraints: item0.constraints.concat(item1.constraints), 2050 overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap, 2051 allows: item0.allows.concat(item1.allows), 2052 backgroundColor: item1.backgroundColor || item0.backgroundColor, 2053 borderColor: item1.borderColor || item0.borderColor, 2054 textColor: item1.textColor || item0.textColor,
2055 classNames: item0.classNames.concat(item1.classNames), 2056 }; 2057 } 2058 2059 var EVENT_NON_DATE_REFINERS = { 2060 id: String, 2061 groupId: String, 2062 title: String, 2063 url: String, 2064 interactive: Boolean, 2065 }; 2066 var EVENT_DATE_REFINERS = { 2067 start: identity, 2068 end: identity, 2069 date: identity, 2070 allDay: Boolean, 2071 }; 2072 var EVENT_REFINERS = __assign(__assign(__assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), { extendedProps: identity }); 2073 function parseEvent(raw, eventSource, context, allowOpenRange, refiners) { 2074 if (refiners === void 0) { refiners = buildEventRefiners(context); } 2075 var _a = refineEventDef(raw, context, refiners), refined = _a.refined, extra = _a.extra; 2076 var defaultAllDay = computeIsDefaultAllDay(eventSource, context); 2077 var recurringRes = parseRecurring(refined, defaultAllDay, context.dateEnv, context.pluginHooks.recurringTypes); 2078 if (recurringRes) { 2079 var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', recurringRes.allDay, Boolean(recurringRes.duration), context); 2080 def.recurringDef = { 2081 typeId: recurringRes.typeId, 2082 typeData: recurringRes.typeData, 2083 duration: recurringRes.duration, 2084 }; 2085 return { def: def, instance: null }; 2086 } 2087 var singleRes = parseSingle(refined, defaultAllDay, context, allowOpenRange); 2088 if (singleRes) { 2089 var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', singleRes.allDay, singleRes.hasEnd, context); 2090 var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo); 2091 return { def: def, instance: instance }; 2092 } 2093 return null; 2094 } 2095 function refineEventDef(raw, context, refiners) { 2096 if (refiners === void 0) { refiners = buildEventRefiners(context); } 2097 return refineProps(raw, refiners); 2098 } 2099 function buildEventRefiners(context) { 2100 return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), context.pluginHooks.eventRefiners); 2101 } 2102 /* 2103 Will NOT populate extendedProps with the leftover properties. 2104 Will NOT populate date-related props. 2105 */ 2106 function parseEventDef(refined, extra, sourceId, allDay, hasEnd, context) { 2107 var def = { 2108 title: refined.title || '', 2109 groupId: refined.groupId || '', 2110 publicId: refined.id || '', 2111 url: refined.url || '', 2112 recurringDef: null, 2113 defId: guid(), 2114 sourceId: sourceId, 2115 allDay: allDay, 2116 hasEnd: hasEnd, 2117 interactive: refined.interactive, 2118 ui: createEventUi(refined, context), 2119 extendedProps: __assign(__assign({}, (refined.extendedProps || {})), extra), 2120 }; 2121 for (var _i = 0, _a = context.pluginHooks.eventDefMemberAdders; _i < _a.length; _i++) { 2122 var memberAdder = _a[_i]; 2123 __assign(def, memberAdder(refined)); 2124 } 2125 // help out EventApi from having user modify props 2126 Object.freeze(def.ui.classNames); 2127 Object.freeze(def.extendedProps); 2128 return def; 2129 } 2130 function parseSingle(refined, defaultAllDay, context, allowOpenRange) { 2131 var allDay = refined.allDay; 2132 var startMeta; 2133 var startMarker = null; 2134 var hasEnd = false; 2135 var endMeta; 2136 var endMarker = null; 2137 var startInput = refined.start != null ? refined.start : refined.date; 2138 startMeta = context.dateEnv.createMarkerMeta(startInput); 2139 if (startMeta) { 2140 startMarker = startMeta.marker; 2141 } 2142 else if (!allowOpenRange) { 2143 return null; 2144 } 2145 if (refined.end != null) { 2146 endMeta = context.dateEnv.createMarkerMeta(refined.end); 2147 } 2148 if (allDay == null) { 2149 if (defaultAllDay != null) { 2150 allDay = defaultAllDay; 2151 } 2152 else { 2153 // fall back to the date props LAST 2154 allDay = (!startMeta || startMeta.isTimeUnspecified) && 2155 (!endMeta || endMeta.isTimeUnspecified);
2156 } 2157 } 2158 if (allDay && startMarker) { 2159 startMarker = startOfDay(startMarker); 2160 } 2161 if (endMeta) { 2162 endMarker = endMeta.marker; 2163 if (allDay) { 2164 endMarker = startOfDay(endMarker); 2165 } 2166 if (startMarker && endMarker <= startMarker) { 2167 endMarker = null; 2168 } 2169 } 2170 if (endMarker) { 2171 hasEnd = true; 2172 } 2173 else if (!allowOpenRange) { 2174 hasEnd = context.options.forceEventDuration || false; 2175 endMarker = context.dateEnv.add(startMarker, allDay ? 2176 context.options.defaultAllDayEventDuration : 2177 context.options.defaultTimedEventDuration); 2178 } 2179 return { 2180 allDay: allDay, 2181 hasEnd: hasEnd, 2182 range: { start: startMarker, end: endMarker }, 2183 forcedStartTzo: startMeta ? startMeta.forcedTzo : null, 2184 forcedEndTzo: endMeta ? endMeta.forcedTzo : null, 2185 }; 2186 } 2187 function computeIsDefaultAllDay(eventSource, context) { 2188 var res = null; 2189 if (eventSource) { 2190 res = eventSource.defaultAllDay; 2191 } 2192 if (res == null) { 2193 res = context.options.defaultAllDay; 2194 } 2195 return res; 2196 } 2197 2198 /* Date stuff that doesn't belong in datelib core 2199 ----------------------------------------------------------------------------------------------------------------------*/ 2200 // given a timed range, computes an all-day range that has the same exact duration, 2201 // but whose start time is aligned with the start of the day. 2202 function computeAlignedDayRange(timedRange) { 2203 var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1; 2204 var start = startOfDay(timedRange.start); 2205 var end = addDays(start, dayCnt); 2206 return { start: start, end: end }; 2207 } 2208 // given a timed range, computes an all-day range based on how for the end date bleeds into the next day 2209 // TODO: give nextDayThreshold a default arg 2210 function computeVisibleDayRange(timedRange, nextDayThreshold) { 2211 if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); } 2212 var startDay = null; 2213 var endDay = null; 2214 if (timedRange.end) { 2215 endDay = startOfDay(timedRange.end); 2216 var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay` 2217 // If the end time is actually inclusively part of the next day and is equal to or 2218 // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`. 2219 // Otherwise, leaving it as inclusive will cause it to exclude `endDay`. 2220 if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) { 2221 endDay = addDays(endDay, 1); 2222 } 2223 } 2224 if (timedRange.start) { 2225 startDay = startOfDay(timedRange.start); // the beginning of the day the range starts 2226 // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day. 2227 if (endDay && endDay <= startDay) { 2228 endDay = addDays(startDay, 1); 2229 } 2230 } 2231 return { start: startDay, end: endDay }; 2232 } 2233 // spans from one day into another? 2234 function isMultiDayRange(range) { 2235 var visibleRange = computeVisibleDayRange(range); 2236 return diffDays(visibleRange.start, visibleRange.end) > 1;
vendor: 16,384 bytes, lines 2237-2621
2237 } 2238 function diffDates(date0, date1, dateEnv, largeUnit) { 2239 if (largeUnit === 'year') { 2240 return createDuration(dateEnv.diffWholeYears(date0, date1), 'year'); 2241 } 2242 if (largeUnit === 'month') { 2243 return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month'); 2244 } 2245 return diffDayAndTime(date0, date1); // returns a duration 2246 } 2247 2248 function parseRange(input, dateEnv) { 2249 var start = null; 2250 var end = null; 2251 if (input.start) { 2252 start = dateEnv.createMarker(input.start); 2253 } 2254 if (input.end) { 2255 end = dateEnv.createMarker(input.end); 2256 } 2257 if (!start && !end) { 2258 return null; 2259 } 2260 if (start && end && end < start) { 2261 return null; 2262 } 2263 return { start: start, end: end }; 2264 } 2265 // SIDE-EFFECT: will mutate ranges. 2266 // Will return a new array result. 2267 function invertRanges(ranges, constraintRange) { 2268 var invertedRanges = []; 2269 var start = constraintRange.start; // the end of the previous range. the start of the new range 2270 var i; 2271 var dateRange; 2272 // ranges need to be in order. required for our date-walking algorithm 2273 ranges.sort(compareRanges); 2274 for (i = 0; i < ranges.length; i += 1) { 2275 dateRange = ranges[i]; 2276 // add the span of time before the event (if there is any) 2277 if (dateRange.start > start) { // compare millisecond time (skip any ambig logic) 2278 invertedRanges.push({ start: start, end: dateRange.start }); 2279 } 2280 if (dateRange.end > start) { 2281 start = dateRange.end; 2282 } 2283 } 2284 // add the span of time after the last event (if there is any) 2285 if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic) 2286 invertedRanges.push({ start: start, end: constraintRange.end }); 2287 } 2288 return invertedRanges; 2289 } 2290 function compareRanges(range0, range1) { 2291 return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first 2292 } 2293 function intersectRanges(range0, range1) { 2294 var start = range0.start, end = range0.end; 2295 var newRange = null; 2296 if (range1.start !== null) { 2297 if (start === null) { 2298 start = range1.start; 2299 } 2300 else { 2301 start = new Date(Math.max(start.valueOf(), range1.start.valueOf())); 2302 } 2303 } 2304 if (range1.end != null) { 2305 if (end === null) { 2306 end = range1.end; 2307 } 2308 else { 2309 end = new Date(Math.min(end.valueOf(), range1.end.valueOf())); 2310 } 2311 } 2312 if (start === null || end === null || start < end) { 2313 newRange = { start: start, end: end }; 2314 } 2315 return newRange; 2316 } 2317 function rangesEqual(range0, range1) { 2318 return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) && 2319 (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf()); 2320 } 2321 function rangesIntersect(range0, range1) { 2322 return (range0.end === null || range1.start === null || range0.end > range1.start) && 2323 (range0.start === null || range1.end === null || range0.start < range1.end); 2324 } 2325 function rangeContainsRange(outerRange, innerRange) { 2326 return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) && 2327 (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end)); 2328 } 2329 function rangeContainsMarker(range, date) { 2330 return (range.start === null || date >= range.start) && 2331 (range.end === null || date < range.end); 2332 } 2333 // If the given date is not within the given range, move it inside. 2334 // (If it's past the end, make it one millisecond before the end). 2335 function constrainMarkerToRange(date, range) { 2336 if (range.start != null && date < range.start) { 2337 return range.start; 2338 } 2339 if (range.end != null && date >= range.end) { 2340 return new Date(range.end.valueOf() - 1); 2341 } 2342 return date; 2343 } 2344 2345 /* 2346 Specifying nextDayThreshold signals that all-day ranges should be sliced. 2347 */ 2348 function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) { 2349 var inverseBgByGroupId = {}; 2350 var inverseBgByDefId = {}; 2351 var defByGroupId = {}; 2352 var bgRanges = []; 2353 var fgRanges = []; 2354 var eventUis = compileEventUis(eventStore.defs, eventUiBases); 2355 for (var defId in eventStore.defs) { 2356 var def = eventStore.defs[defId]; 2357 var ui = eventUis[def.defId]; 2358 if (ui.display === 'inverse-background') { 2359 if (def.groupId) { 2360 inverseBgByGroupId[def.groupId] = []; 2361 if (!defByGroupId[def.groupId]) { 2362 defByGroupId[def.groupId] = def; 2363 } 2364 } 2365 else { 2366 inverseBgByDefId[defId] = []; 2367 } 2368 } 2369 } 2370 for (var instanceId in eventStore.instances) { 2371 var instance = eventStore.instances[instanceId]; 2372 var def = eventStore.defs[instance.defId]; 2373 var ui = eventUis[def.defId]; 2374 var origRange = instance.range; 2375 var normalRange = (!def.allDay && nextDayThreshold) ? 2376 computeVisibleDayRange(origRange, nextDayThreshold) : 2377 origRange; 2378 var slicedRange = intersectRanges(normalRange, framingRange); 2379 if (slicedRange) { 2380 if (ui.display === 'inverse-background') { 2381 if (def.groupId) { 2382 inverseBgByGroupId[def.groupId].push(slicedRange); 2383 } 2384 else { 2385 inverseBgByDefId[instance.defId].push(slicedRange); 2386 } 2387 } 2388 else if (ui.display !== 'none') { 2389 (ui.display === 'background' ? bgRanges : fgRanges).push({ 2390 def: def, 2391 ui: ui, 2392 instance: instance, 2393 range: slicedRange, 2394 isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(), 2395 isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf(), 2396 }); 2397 } 2398 } 2399 } 2400 for (var groupId in inverseBgByGroupId) { // BY GROUP 2401 var ranges = inverseBgByGroupId[groupId]; 2402 var invertedRanges = invertRanges(ranges, framingRange); 2403 for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) { 2404 var invertedRange = invertedRanges_1[_i]; 2405 var def = defByGroupId[groupId]; 2406 var ui = eventUis[def.defId]; 2407 bgRanges.push({ 2408 def: def, 2409 ui: ui, 2410 instance: null, 2411 range: invertedRange, 2412 isStart: false, 2413 isEnd: false, 2414 }); 2415 } 2416 } 2417 for (var defId in inverseBgByDefId) { 2418 var ranges = inverseBgByDefId[defId]; 2419 var invertedRanges = invertRanges(ranges, framingRange); 2420 for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) { 2421 var invertedRange = invertedRanges_2[_a]; 2422 bgRanges.push({ 2423 def: eventStore.defs[defId], 2424 ui: eventUis[defId], 2425 instance: null, 2426 range: invertedRange, 2427 isStart: false, 2428 isEnd: false, 2429 }); 2430 } 2431 } 2432 return { bg: bgRanges, fg: fgRanges }; 2433 } 2434 function hasBgRendering(def) { 2435 return def.ui.display === 'background' || def.ui.display === 'inverse-background'; 2436 } 2437 function setElSeg(el, seg) { 2438 el.fcSeg = seg; 2439 } 2440 function getElSeg(el) { 2441 return el.fcSeg || 2442 el.parentNode.fcSeg || // for the harness 2443 null; 2444 } 2445 // event ui computation 2446 function compileEventUis(eventDefs, eventUiBases) { 2447 return mapHash(eventDefs, function (eventDef) { return compileEventUi(eventDef, eventUiBases); }); 2448 } 2449 function compileEventUi(eventDef, eventUiBases) { 2450 var uis = []; 2451 if (eventUiBases['']) { 2452 uis.push(eventUiBases['']); 2453 } 2454 if (eventUiBases[eventDef.defId]) { 2455 uis.push(eventUiBases[eventDef.defId]); 2456 } 2457 uis.push(eventDef.ui); 2458 return combineEventUis(uis); 2459 } 2460 function sortEventSegs(segs, eventOrderSpecs) { 2461 var objs = segs.map(buildSegCompareObj); 2462 objs.sort(function (obj0, obj1) { return compareByFieldSpecs(obj0, obj1, eventOrderSpecs); }); 2463 return objs.map(function (c) { return c._seg; }); 2464 } 2465 // returns a object with all primitive props that can be compared 2466 function buildSegCompareObj(seg) { 2467 var eventRange = seg.eventRange; 2468 var eventDef = eventRange.def; 2469 var range = eventRange.instance ? eventRange.instance.range : eventRange.range; 2470 var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events 2471 var end = range.end ? range.end.valueOf() : 0; // " 2472 return __assign(__assign(__assign({}, eventDef.extendedProps), eventDef), { id: eventDef.publicId, start: start, 2473 end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg }); 2474 } 2475 function computeSegDraggable(seg, context) { 2476 var pluginHooks = context.pluginHooks; 2477 var transformers = pluginHooks.isDraggableTransformers; 2478 var _a = seg.eventRange, def = _a.def, ui = _a.ui; 2479 var val = ui.startEditable; 2480 for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) { 2481 var transformer = transformers_1[_i]; 2482 val = transformer(val, def, ui, context); 2483 } 2484 return val; 2485 } 2486 function computeSegStartResizable(seg, context) { 2487 return seg.isStart && seg.eventRange.ui.durationEditable && context.options.eventResizableFromStart; 2488 } 2489 function computeSegEndResizable(seg, context) { 2490 return seg.isEnd && seg.eventRange.ui.durationEditable; 2491 } 2492 function buildSegTimeText(seg, timeFormat, context, defaultDisplayEventTime, // defaults to true 2493 defaultDisplayEventEnd, // defaults to true 2494 startOverride, endOverride) { 2495 var dateEnv = context.dateEnv, options = context.options; 2496 var displayEventTime = options.displayEventTime, displayEventEnd = options.displayEventEnd; 2497 var eventDef = seg.eventRange.def; 2498 var eventInstance = seg.eventRange.instance; 2499 if (displayEventTime == null) { 2500 displayEventTime = defaultDisplayEventTime !== false; 2501 } 2502 if (displayEventEnd == null) { 2503 displayEventEnd = defaultDisplayEventEnd !== false; 2504 } 2505 var wholeEventStart = eventInstance.range.start; 2506 var wholeEventEnd = eventInstance.range.end; 2507 var segStart = startOverride || seg.start || seg.eventRange.range.start; 2508 var segEnd = endOverride || seg.end || seg.eventRange.range.end; 2509 var isStartDay = startOfDay(wholeEventStart).valueOf() === startOfDay(segStart).valueOf(); 2510 var isEndDay = startOfDay(addMs(wholeEventEnd, -1)).valueOf() === startOfDay(addMs(segEnd, -1)).valueOf(); 2511 if (displayEventTime && !eventDef.allDay && (isStartDay || isEndDay)) { 2512 segStart = isStartDay ? wholeEventStart : segStart; 2513 segEnd = isEndDay ? wholeEventEnd : segEnd; 2514 if (displayEventEnd && eventDef.hasEnd) { 2515 return dateEnv.formatRange(segStart, segEnd, timeFormat, { 2516 forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo, 2517 forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo, 2518 }); 2519 } 2520 return dateEnv.format(segStart, timeFormat, { 2521 forcedTzo: startOverride ? null : eventInstance.forcedStartTzo, // nooooo, same 2522 }); 2523 } 2524 return ''; 2525 } 2526 function getSegMeta(seg, todayRange, nowDate) { 2527 var segRange = seg.eventRange.range; 2528 return { 2529 isPast: segRange.end < (nowDate || todayRange.start), 2530 isFuture: segRange.start >= (nowDate || todayRange.end), 2531 isToday: todayRange && rangeContainsMarker(todayRange, segRange.start), 2532 }; 2533 } 2534 function getEventClassNames(props) { 2535 var classNames = ['fc-event']; 2536 if (props.isMirror) { 2537 classNames.push('fc-event-mirror'); 2538 } 2539 if (props.isDraggable) { 2540 classNames.push('fc-event-draggable'); 2541 } 2542 if (props.isStartResizable || props.isEndResizable) { 2543 classNames.push('fc-event-resizable'); 2544 } 2545 if (props.isDragging) { 2546 classNames.push('fc-event-dragging'); 2547 } 2548 if (props.isResizing) { 2549 classNames.push('fc-event-resizing'); 2550 } 2551 if (props.isSelected) { 2552 classNames.push('fc-event-selected'); 2553 } 2554 if (props.isStart) { 2555 classNames.push('fc-event-start'); 2556 } 2557 if (props.isEnd) { 2558 classNames.push('fc-event-end'); 2559 } 2560 if (props.isPast) { 2561 classNames.push('fc-event-past'); 2562 } 2563 if (props.isToday) { 2564 classNames.push('fc-event-today'); 2565 } 2566 if (props.isFuture) { 2567 classNames.push('fc-event-future'); 2568 } 2569 return classNames; 2570 } 2571 function buildEventRangeKey(eventRange) { 2572 return eventRange.instance 2573 ? eventRange.instance.instanceId 2574 : eventRange.def.defId + ":" + eventRange.range.start.toISOString(); 2575 // inverse-background events don't have specific instances. TODO: better solution 2576 } 2577 function getSegAnchorAttrs(seg, context) { 2578 var _a = seg.eventRange, def = _a.def, instance = _a.instance; 2579 var url = def.url; 2580 if (url) { 2581 return { href: url }; 2582 } 2583 var emitter = context.emitter, options = context.options; 2584 var eventInteractive = options.eventInteractive; 2585 if (eventInteractive == null) { 2586 eventInteractive = def.interactive; 2587 if (eventInteractive == null) { 2588 eventInteractive = Boolean(emitter.hasHandlers('eventClick')); 2589 } 2590 } 2591 // mock what happens in EventClicking 2592 if (eventInteractive) { 2593 // only attach keyboard-related handlers because click handler is already done in EventClicking 2594 return createAriaKeyboardAttrs(function (ev) { 2595 emitter.trigger('eventClick', { 2596 el: ev.target, 2597 event: new EventApi(context, def, instance), 2598 jsEvent: ev, 2599 view: context.viewApi, 2600 }); 2601 }); 2602 } 2603 return {}; 2604 } 2605 2606 var STANDARD_PROPS = { 2607 start: identity, 2608 end: identity, 2609 allDay: Boolean, 2610 }; 2611 function parseDateSpan(raw, dateEnv, defaultDuration) { 2612 var span = parseOpenDateSpan(raw, dateEnv); 2613 var range = span.range; 2614 if (!range.start) { 2615 return null; 2616 } 2617 if (!range.end) { 2618 if (defaultDuration == null) { 2619 return null; 2620 } 2621 range.end = dateEnv.add(range.start, defaultDuration);�
2621 2622 } 2623 return span; 2624 } 2625 /* 2626 TODO: somehow combine with parseRange? 2627 Will return null if the start/end props were present but parsed invalidly. 2628 */ 2629 function parseOpenDateSpan(raw, dateEnv) { 2630 var _a = refineProps(raw, STANDARD_PROPS), standardProps = _a.refined, extra = _a.extra; 2631 var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null; 2632 var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null; 2633 var allDay = standardProps.allDay; 2634 if (allDay == null) { 2635 allDay = (startMeta && startMeta.isTimeUnspecified) && 2636 (!endMeta || endMeta.isTimeUnspecified); 2637 } 2638 return __assign({ range: { 2639 start: startMeta ? startMeta.marker : null, 2640 end: endMeta ? endMeta.marker : null, 2641 }, allDay: allDay }, extra); 2642 } 2643 function isDateSpansEqual(span0, span1) { 2644 return rangesEqual(span0.range, span1.range) && 2645 span0.allDay === span1.allDay && 2646 isSpanPropsEqual(span0, span1); 2647 } 2648 // the NON-DATE-RELATED props 2649 function isSpanPropsEqual(span0, span1) { 2650 for (var propName in span1) { 2651 if (propName !== 'range' && propName !== 'allDay') { 2652 if (span0[propName] !== span1[propName]) { 2653 return false; 2654 } 2655 } 2656 } 2657 // are there any props that span0 has that span1 DOESN'T have? 2658 // both have range/allDay, so no need to special-case. 2659 for (var propName in span0) { 2660 if (!(propName in span1)) { 2661 return false; 2662 } 2663 } 2664 return true; 2665 } 2666 function buildDateSpanApi(span, dateEnv) { 2667 return __assign(__assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), { allDay: span.allDay }); 2668 } 2669 function buildRangeApiWithTimeZone(range, dateEnv, omitTime) { 2670 return __assign(__assign({}, buildRangeApi(range, dateEnv, omitTime)), { timeZone: dateEnv.timeZone }); 2671 } 2672 function buildRangeApi(range, dateEnv, omitTime) { 2673 return { 2674 start: dateEnv.toDate(range.start), 2675 end: dateEnv.toDate(range.end), 2676 startStr: dateEnv.formatIso(range.start, { omitTime: omitTime }), 2677 endStr: dateEnv.formatIso(range.end, { omitTime: omitTime }), 2678 }; 2679 } 2680 function fabricateEventRange(dateSpan, eventUiBases, context) { 2681 var res = refineEventDef({ editable: false }, context); 2682 var def = parseEventDef(res.refined, res.extra, '', // sourceId 2683 dateSpan.allDay, true, // hasEnd 2684 context); 2685 return { 2686 def: def, 2687 ui: compileEventUi(def, eventUiBases), 2688 instance: createEventInstance(def.defId, dateSpan.range), 2689 range: dateSpan.range, 2690 isStart: true, 2691 isEnd: true, 2692 }; 2693 } 2694 2695 function triggerDateSelect(selection, pev, context) { 2696 context.emitter.trigger('select', __assign(__assign({}, buildDateSpanApiWithContext(selection, context)), { jsEvent: pev ? pev.origEvent : null, view: context.viewApi || context.calendarApi.view })); 2697 } 2698 function triggerDateUnselect(pev, context) { 2699 context.emitter.trigger('unselect', { 2700 jsEvent: pev ? pev.origEvent : null, 2701 view: context.viewApi || context.calendarApi.view, 2702 }); 2703 } 2704 function buildDateSpanApiWithContext(dateSpan, context) { 2705 var props = {}; 2706 for (var _i = 0, _a = context.pluginHooks.dateSpanTransforms; _i < _a.length; _i++) { 2707 var transform = _a[_i]; 2708 __assign(props, transform(dateSpan, context)); 2709 } 2710 __assign(props, buildDateSpanApi(dateSpan, context.dateEnv)); 2711 return props; 2712 } 2713 // Given an event's allDay status and start date, return what its fallback end date should be. 2714 // TODO: rename to computeDefaultEventEnd 2715 function getDefaultEventEnd(allDay, marker, context) { 2716 var dateEnv = context.dateEnv, options = context.options; 2717 var end = marker; 2718 if (allDay) { 2719 end = startOfDay(end); 2720 end = dateEnv.add(end, options.defaultAllDayEventDuration); 2721 } 2722 else { 2723 end = dateEnv.add(end, options.defaultTimedEventDuration); 2724 } 2725 return end; 2726 } 2727 2728 // applies the mutation to ALL defs/instances within the event store 2729 function applyMutationToEventStore(eventStore, eventConfigBase, mutation, context) { 2730 var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase); 2731 var dest = createEmptyEventStore(); 2732 for (var defId in eventStore.defs) { 2733 var def = eventStore.defs[defId]; 2734 dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, context); 2735 } 2736 for (var instanceId in eventStore.instances) { 2737 var instance = eventStore.instances[instanceId]; 2738 var def = dest.defs[instance.defId]; // important to grab the newly modified def 2739 dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, context); 2740 } 2741 return dest; 2742 } 2743 function applyMutationToEventDef(eventDef, eventConfig, mutation, context) { 2744 var standardProps = mutation.standardProps || {}; 2745 // if hasEnd has not been specified, guess a good value based on deltas. 2746 // if duration will change, there's no way the default duration will persist, 2747 // and thus, we need to mark the event as having a real end 2748 if (standardProps.hasEnd == null && 2749 eventConfig.durationEditable && 2750 (mutation.startDelta || mutation.endDelta)) { 2751 standardProps.hasEnd = true; // TODO: is this mutation okay? 2752 } 2753 var copy = __assign(__assign(__assign({}, eventDef), standardProps), { ui: __assign(__assign({}, eventDef.ui), standardProps.ui) }); 2754 if (mutation.extendedProps) { 2755 copy.extendedProps = __assign(__assign({}, copy.extendedProps), mutation.extendedProps); 2756 } 2757 for (var _i = 0, _a = context.pluginHooks.eventDefMutationAppliers; _i < _a.length; _i++) { 2758 var applier = _a[_i]; 2759 applier(copy, mutation, context); 2760 } 2761 if (!copy.hasEnd && context.options.forceEventDuration) { 2762 copy.hasEnd = true; 2763 } 2764 return copy; 2765 } 2766 function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef 2767 eventConfig, mutation, context) { 2768 var dateEnv = context.dateEnv; 2769 var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true; 2770 var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false; 2771 var copy = __assign({}, eventInstance); 2772 if (forceAllDay) { 2773 copy.range = computeAlignedDayRange(copy.range); 2774 } 2775 if (mutation.datesDelta && eventConfig.startEditable) { 2776 copy.range = { 2777 start: dateEnv.add(copy.range.start, mutation.datesDelta), 2778 end: dateEnv.add(copy.range.end, mutation.datesDelta), 2779 }; 2780 } 2781 if (mutation.startDelta && eventConfig.durationEditable) { 2782 copy.range = { 2783 start: dateEnv.add(copy.range.start, mutation.startDelta), 2784 end: copy.range.end, 2785 }; 2786 } 2787 if (mutation.endDelta && eventConfig.durationEditable) { 2788 copy.range = { 2789 start: copy.range.start, 2790 end: dateEnv.add(copy.range.end, mutation.endDelta), 2791 }; 2792 } 2793 if (clearEnd) { 2794 copy.range = { 2795 start: copy.range.start, 2796 end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context), 2797 }; 2798 } 2799 // in case event was all-day but the supplied deltas were not 2800 // better util for this? 2801 if (eventDef.allDay) { 2802 copy.range = { 2803 start: startOfDay(copy.range.start), 2804 end: startOfDay(copy.range.end), 2805 }; 2806 } 2807 // handle invalid durations 2808 if (copy.range.end < copy.range.start) { 2809 copy.range.end = getDefaultEventEnd(eventDef.allDay, copy.range.start, context); 2810 } 2811 return copy; 2812 } 2813 2814 // no public types yet. when there are, export from: 2815 // import {} from './api-type-deps' 2816 var ViewApi = /** @class */ (function () { 2817 function ViewApi(type, getCurrentData, dateEnv) { 2818 this.type = type; 2819 this.getCurrentData = getCurrentData; 2820 this.dateEnv = dateEnv; 2821 } 2822 Object.defineProperty(ViewApi.prototype, "calendar", { 2823 get: function () { 2824 return this.getCurrentData().calendarApi; 2825 }, 2826 enumerable: false, 2827 configurable: true 2828 }); 2829 Object.defineProperty(ViewApi.prototype, "title", { 2830 get: function () { 2831 return this.getCurrentData().viewTitle; 2832 }, 2833 enumerable: false, 2834 configurable: true 2835 }); 2836 Object.defineProperty(ViewApi.prototype, "activeStart", { 2837 get: function () { 2838 return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start); 2839 }, 2840 enumerable: false, 2841 configurable: true 2842 }); 2843 Object.defineProperty(ViewApi.prototype, "activeEnd", { 2844 get: function () { 2845 return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end); 2846 }, 2847 enumerable: false, 2848 configurable: true 2849 }); 2850 Object.defineProperty(ViewApi.prototype, "currentStart", { 2851 get: function () { 2852 return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start); 2853 }, 2854 enumerable: false, 2855 configurable: true 2856 }); 2857 Object.defineProperty(ViewApi.prototype, "currentEnd", { 2858 get: function () { 2859 return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end); 2860 }, 2861 enumerable: false, 2862 configurable: true 2863 }); 2864 ViewApi.prototype.getOption = function (name) { 2865 return this.getCurrentData().options[name]; // are the view-specific options 2866 }; 2867 return ViewApi; 2868 }()); 2869 2870 var EVENT_SOURCE_REFINERS$1 = { 2871 id: String, 2872 defaultAllDay: Boolean, 2873 url: String, 2874 format: String,
2875 events: identity, 2876 eventDataTransform: identity, 2877 // for any network-related sources 2878 success: identity, 2879 failure: identity, 2880 }; 2881 function parseEventSource(raw, context, refiners) { 2882 if (refiners === void 0) { refiners = buildEventSourceRefiners(context); } 2883 var rawObj; 2884 if (typeof raw === 'string') { 2885 rawObj = { url: raw }; 2886 } 2887 else if (typeof raw === 'function' || Array.isArray(raw)) { 2888 rawObj = { events: raw }; 2889 } 2890 else if (typeof raw === 'object' && raw) { // not null 2891 rawObj = raw; 2892 } 2893 if (rawObj) { 2894 var _a = refineProps(rawObj, refiners), refined = _a.refined, extra = _a.extra; 2895 var metaRes = buildEventSourceMeta(refined, context); 2896 if (metaRes) { 2897 return { 2898 _raw: raw, 2899 isFetching: false, 2900 latestFetchId: '', 2901 fetchRange: null, 2902 defaultAllDay: refined.defaultAllDay, 2903 eventDataTransform: refined.eventDataTransform, 2904 success: refined.success, 2905 failure: refined.failure, 2906 publicId: refined.id || '', 2907 sourceId: guid(), 2908 sourceDefId: metaRes.sourceDefId, 2909 meta: metaRes.meta, 2910 ui: createEventUi(refined, context), 2911 extendedProps: extra, 2912 }; 2913 } 2914 } 2915 return null; 2916 } 2917 function buildEventSourceRefiners(context) { 2918 return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS$1), context.pluginHooks.eventSourceRefiners); 2919 } 2920 function buildEventSourceMeta(raw, context) { 2921 var defs = context.pluginHooks.eventSourceDefs; 2922 for (var i = defs.length - 1; i >= 0; i -= 1) { // later-added plugins take precedence 2923 var def = defs[i]; 2924 var meta = def.parseMeta(raw); 2925 if (meta) { 2926 return { sourceDefId: i, meta: meta }; 2927 } 2928 } 2929 return null; 2930 } 2931 2932 function reduceCurrentDate(currentDate, action) { 2933 switch (action.type) { 2934 case 'CHANGE_DATE': 2935 return action.dateMarker; 2936 default: 2937 return currentDate; 2938 } 2939 } 2940 function getInitialDate(options, dateEnv) { 2941 var initialDateInput = options.initialDate; 2942 // compute the initial ambig-timezone date 2943 if (initialDateInput != null) { 2944 return dateEnv.createMarker(initialDateInput); 2945 } 2946 return getNow(options.now, dateEnv); // getNow already returns unzoned 2947 } 2948 function getNow(nowInput, dateEnv) { 2949 if (typeof nowInput === 'function') { 2950 nowInput = nowInput(); 2951 } 2952 if (nowInput == null) { 2953 return dateEnv.createNowMarker(); 2954 } 2955 return dateEnv.createMarker(nowInput); 2956 } 2957 2958 var CalendarApi = /** @class */ (function () { 2959 function CalendarApi() { 2960 } 2961 CalendarApi.prototype.getCurrentData = function () { 2962 return this.currentDataManager.getCurrentData(); 2963 }; 2964 CalendarApi.prototype.dispatch = function (action) { 2965 return this.currentDataManager.dispatch(action); 2966 }; 2967 Object.defineProperty(CalendarApi.prototype, "view", { 2968 get: function () { return this.getCurrentData().viewApi; } // for public API 2969 , 2970 enumerable: false, 2971 configurable: true 2972 }); 2973 CalendarApi.prototype.batchRendering = function (callback) { 2974 callback(); 2975 }; 2976 CalendarApi.prototype.updateSize = function () { 2977 this.trigger('_resize', true); 2978 }; 2979 // Options 2980 // ----------------------------------------------------------------------------------------------------------------- 2981 CalendarApi.prototype.setOption = function (name, val) { 2982 this.dispatch({ 2983 type: 'SET_OPTION', 2984 optionName: name, 2985 rawOptionValue: val, 2986 }); 2987 }; 2988 CalendarApi.prototype.getOption = function (name) { 2989 return this.currentDataManager.currentCalendarOptionsInput[name]; 2990 }; 2991 CalendarApi.prototype.getAvailableLocaleCodes = function () { 2992 return Object.keys(this.getCurrentData().availableRawLocales); 2993 }; 2994 // Trigger 2995 // ----------------------------------------------------------------------------------------------------------------- 2996 CalendarApi.prototype.on = function (handlerName, handler) { 2997 var currentDataManager = this.currentDataManager; 2998 if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) { 2999 currentDataManager.emitter.on(handlerName, handler); 3000 } 3001 else { 3002 console.warn("Unknown listener name '" + handlerName + "'"); 3003 } 3004 }; 3005 CalendarApi.prototype.off = function (handlerName, handler) { 3006 this.currentDataManager.emitter.off(handlerName, handler); 3007 }; 3008 // not meant for public use 3009 CalendarApi.prototype.trigger = function (handlerName) { 3010 var _a; 3011 var args = []; 3012 for (var _i = 1; _i < arguments.length; _i++) { 3013 args[_i - 1] = arguments[_i]; 3014 } 3015 (_a = this.currentDataManager.emitter).trigger.apply(_a, __spreadArray([handlerName], args)); 3016 }; 3017 // View 3018 // ----------------------------------------------------------------------------------------------------------------- 3019 CalendarApi.prototype.changeView = function (viewType, dateOrRange) { 3020 var _this = this; 3021 this.batchRendering(function () { 3022 _this.unselect(); 3023 if (dateOrRange) { 3024 if (dateOrRange.start && dateOrRange.end) { // a range 3025 _this.dispatch({ 3026 type: 'CHANGE_VIEW_TYPE', 3027 viewType: viewType, 3028 }); 3029 _this.dispatch({ 3030 type: 'SET_OPTION', 3031 optionName: 'visibleRange',
3032 rawOptionValue: dateOrRange, 3033 }); 3034 } 3035 else { 3036 var dateEnv = _this.getCurrentData().dateEnv; 3037 _this.dispatch({ 3038 type: 'CHANGE_VIEW_TYPE', 3039 viewType: viewType, 3040 dateMarker: dateEnv.createMarker(dateOrRange), 3041 }); 3042 } 3043 } 3044 else { 3045 _this.dispatch({ 3046 type: 'CHANGE_VIEW_TYPE', 3047 viewType: viewType, 3048 }); 3049 } 3050 }); 3051 }; 3052 // Forces navigation to a view for the given date. 3053 // `viewType` can be a specific view name or a generic one like "week" or "day". 3054 // needs to change 3055 CalendarApi.prototype.zoomTo = function (dateMarker, viewType) { 3056 var state = this.getCurrentData(); 3057 var spec; 3058 viewType = viewType || 'day'; // day is default zoom 3059 spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType); 3060 this.unselect(); 3061 if (spec) { 3062 this.dispatch({ 3063 type: 'CHANGE_VIEW_TYPE', 3064 viewType: spec.type, 3065 dateMarker: dateMarker, 3066 }); 3067 } 3068 else { 3069 this.dispatch({ 3070 type: 'CHANGE_DATE', 3071 dateMarker: dateMarker, 3072 }); 3073 } 3074 }; 3075 // Given a duration singular unit, like "week" or "day", finds a matching view spec. 3076 // Preference is given to views that have corresponding buttons. 3077 CalendarApi.prototype.getUnitViewSpec = function (unit) { 3078 var _a = this.getCurrentData(), viewSpecs = _a.viewSpecs, toolbarConfig = _a.toolbarConfig; 3079 var viewTypes = [].concat(toolbarConfig.header ? toolbarConfig.header.viewsWithButtons : [], toolbarConfig.footer ? toolbarConfig.footer.viewsWithButtons : []); 3080 var i; 3081 var spec; 3082 for (var viewType in viewSpecs) { 3083 viewTypes.push(viewType); 3084 } 3085 for (i = 0; i < viewTypes.length; i += 1) { 3086 spec = viewSpecs[viewTypes[i]]; 3087 if (spec) { 3088 if (spec.singleUnit === unit) { 3089 return spec; 3090 } 3091 } 3092 } 3093 return null; 3094 }; 3095 // Current Date 3096 // ----------------------------------------------------------------------------------------------------------------- 3097 CalendarApi.prototype.prev = function () { 3098 this.unselect(); 3099 this.dispatch({ type: 'PREV' }); 3100 }; 3101 CalendarApi.prototype.next = function () { 3102 this.unselect(); 3103 this.dispatch({ type: 'NEXT' }); 3104 }; 3105 CalendarApi.prototype.prevYear = function () { 3106 var state = this.getCurrentData(); 3107 this.unselect(); 3108 this.dispatch({ 3109 type: 'CHANGE_DATE', 3110 dateMarker: state.dateEnv.addYears(state.currentDate, -1), 3111 }); 3112 }; 3113 CalendarApi.prototype.nextYear = function () { 3114 var state = this.getCurrentData(); 3115 this.unselect(); 3116 this.dispatch({ 3117 type: 'CHANGE_DATE', 3118 dateMarker: state.dateEnv.addYears(state.currentDate, 1), 3119 }); 3120 }; 3121 CalendarApi.prototype.today = function () { 3122 var state = this.getCurrentData(); 3123 this.unselect(); 3124 this.dispatch({ 3125 type: 'CHANGE_DATE', 3126 dateMarker: getNow(state.calendarOptions.now, state.dateEnv), 3127 }); 3128 }; 3129 CalendarApi.prototype.gotoDate = function (zonedDateInput) { 3130 var state = this.getCurrentData(); 3131 this.unselect(); 3132 this.dispatch({ 3133 type: 'CHANGE_DATE', 3134 dateMarker: state.dateEnv.createMarker(zonedDateInput), 3135 }); 3136 }; 3137 CalendarApi.prototype.incrementDate = function (deltaInput) { 3138 var state = this.getCurrentData(); 3139 var delta = createDuration(deltaInput); 3140 if (delta) { // else, warn about invalid input? 3141 this.unselect(); 3142 this.dispatch({ 3143 type: 'CHANGE_DATE', 3144 dateMarker: state.dateEnv.add(state.currentDate, delta), 3145 }); 3146 } 3147 }; 3148 // for external API 3149 CalendarApi.prototype.getDate = function () { 3150 var state = this.getCurrentData(); 3151 return state.dateEnv.toDate(state.currentDate); 3152 }; 3153 // Date Formatting Utils 3154 // ----------------------------------------------------------------------------------------------------------------- 3155 CalendarApi.prototype.formatDate = function (d, formatter) { 3156 var dateEnv = this.getCurrentData().dateEnv; 3157 return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter)); 3158 }; 3159 // `settings` is for formatter AND isEndExclusive 3160 CalendarApi.prototype.formatRange = function (d0, d1, settings) { 3161 var dateEnv = this.getCurrentData().dateEnv; 3162 return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings), settings); 3163 }; 3164 CalendarApi.prototype.formatIso = function (d, omitTime) { 3165 var dateEnv = this.getCurrentData().dateEnv; 3166 return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime }); 3167 }; 3168 // Date Selection / Event Selection / DayClick 3169 // ----------------------------------------------------------------------------------------------------------------- 3170 // this public method receives start/end dates in any format, with any timezone 3171 // NOTE: args were changed from v3 3172 CalendarApi.prototype.select = function (dateOrObj, endDate) { 3173 var selectionInput; 3174 if (endDate == null) { 3175 if (dateOrObj.start != null) { 3176 selectionInput = dateOrObj; 3177 } 3178 else { 3179 selectionInput = { 3180 start: dateOrObj, 3181 end: null, 3182 }; 3183 } 3184 } 3185 else { 3186 selectionInput = { 3187 start: dateOrObj, 3188 end: endDate, 3189 }; 3190 } 3191 var state = this.getCurrentData(); 3192 var selection = parseDateSpan(selectionInput, state.dateEnv, createDuration({ days: 1 })); 3193 if (selection) { // throw parse error otherwise? 3194 this.dispatch({ type: 'SELECT_DATES', selection: selection }); 3195 triggerDateSelect(selection, null, state); 3196 } 3197 }; 3198 // public method 3199 CalendarApi.prototype.unselect = function (pev) { 3200 var state = this.getCurrentData(); 3201 if (state.dateSelection) { 3202 this.dispatch({ type: 'UNSELECT_DATES' }); 3203 triggerDateUnselect(pev, state); 3204 } 3205 }; 3206 // Public Events API 3207 // ----------------------------------------------------------------------------------------------------------------- 3208 CalendarApi.prototype.addEvent = function (eventInput, sourceIn
3208put) { 3209 if (eventInput instanceof EventApi) { 3210 var def = eventInput._def; 3211 var instance = eventInput._instance; 3212 var currentData = this.getCurrentData(); 3213 // not already present? don't want to add an old snapshot 3214 if (!currentData.eventStore.defs[def.defId]) { 3215 this.dispatch({ 3216 type: 'ADD_EVENTS', 3217 eventStore: eventTupleToStore({ def: def, instance: instance }), // TODO: better util for two args? 3218 }); 3219 this.triggerEventAdd(eventInput); 3220 } 3221 return eventInput; 3222 } 3223 var state = this.getCurrentData(); 3224 var eventSource; 3225 if (sourceInput instanceof EventSourceApi) { 3226 eventSource = sourceInput.internalEventSource; 3227 } 3228 else if (typeof sourceInput === 'boolean') { 3229 if (sourceInput) { // true. part of the first event source 3230 eventSource = hashValuesToArray(state.eventSources)[0]; 3231 } 3232 } 3233 else if (sourceInput != null) { // an ID. accepts a number too 3234 var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function 3235 if (!sourceApi) { 3236 console.warn("Could not find an event source with ID \"" + sourceInput + "\""); // TODO: test 3237 return null; 3238 } 3239 eventSource = sourceApi.internalEventSource; 3240 } 3241 var tuple = parseEvent(eventInput, eventSource, state, false); 3242 if (tuple) { 3243 var newEventApi = new EventApi(state, tuple.def, tuple.def.recurringDef ? null : tuple.instance); 3244 this.dispatch({ 3245 type: 'ADD_EVENTS', 3246 eventStore: eventTupleToStore(tuple), 3247 }); 3248 this.triggerEventAdd(newEventApi); 3249 return newEventApi; 3250 } 3251 return null; 3252 }; 3253 CalendarApi.prototype.triggerEventAdd = function (eventApi) { 3254 var _this = this; 3255 var emitter = this.getCurrentData().emitter; 3256 emitter.trigger('eventAdd', { 3257 event: eventApi, 3258 relatedEvents: [], 3259 revert: function () { 3260 _this.dispatch({ 3261 type: 'REMOVE_EVENTS', 3262 eventStore: eventApiToStore(eventApi), 3263 }); 3264 }, 3265 }); 3266 }; 3267 // TODO: optimize 3268 CalendarApi.prototype.getEventById = function (id) { 3269 var state = this.getCurrentData(); 3270 var _a = state.eventStore, defs = _a.defs, instances = _a.instances; 3271 id = String(id); 3272 for (var defId in defs) { 3273 var def = defs[defId]; 3274 if (def.publicId === id) { 3275 if (def.recurringDef) { 3276 return new EventApi(state, def, null); 3277 } 3278 for (var instanceId in instances) { 3279 var instance = instances[instanceId]; 3280 if (instance.defId === def.defId) { 3281 return new EventApi(state, def, instance); 3282 } 3283 } 3284 } 3285 } 3286 return null; 3287 }; 3288 CalendarApi.prototype.getEvents = function () { 3289 var currentData = this.getCurrentData(); 3290 return buildEventApis(currentData.eventStore, currentData); 3291 }; 3292 CalendarApi.prototype.removeAllEvents = function () { 3293 this.dispatch({ type: 'REMOVE_ALL_EVENTS' }); 3294 }; 3295 // Public Event Sources API 3296 // ----------------------------------------------------------------------------------------------------------------- 3297 CalendarApi.prototype.getEventSources = function () { 3298 var state = this.getCurrentData(); 3299 var sourceHash = state.eventSources; 3300 var sourceApis = []; 3301 for (var internalId in sourceHash) { 3302 sourceApis.push(new EventSourceApi(state, sourceHash[internalId])); 3303 } 3304 return sourceApis; 3305 }; 3306 CalendarApi.prototype.getEventSourceById = function (id) { 3307 var state = this.getCurrentData(); 3308 var sourceHash = state.eventSources; 3309 id = String(id); 3310 for (var sourceId in sourceHash) { 3311 if (sourceHash[sourceId].publicId === id) { 3312 return new EventSourceApi(state, sourceHash[sourceId]); 3313 } 3314 } 3315 return null; 3316 }; 3317 CalendarApi.prototype.addEventSource = function (sourceInput) { 3318 var state = this.getCurrentData(); 3319 if (sourceInput instanceof EventSourceApi) { 3320 // not already present? don't want to add an old snapshot
3321 if (!state.eventSources[sourceInput.internalEventSource.sourceId]) { 3322 this.dispatch({ 3323 type: 'ADD_EVENT_SOURCES', 3324 sources: [sourceInput.internalEventSource], 3325 }); 3326 } 3327 return sourceInput; 3328 } 3329 var eventSource = parseEventSource(sourceInput, state); 3330 if (eventSource) { // TODO: error otherwise? 3331 this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] }); 3332 return new EventSourceApi(state, eventSource); 3333 } 3334 return null; 3335 }; 3336 CalendarApi.prototype.removeAllEventSources = function () { 3337 this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' }); 3338 }; 3339 CalendarApi.prototype.refetchEvents = function () { 3340 this.dispatch({ type: 'FETCH_EVENT_SOURCES', isRefetch: true }); 3341 }; 3342 // Scroll 3343 // ----------------------------------------------------------------------------------------------------------------- 3344 CalendarApi.prototype.scrollToTime = function (timeInput) { 3345 var time = createDuration(timeInput); 3346 if (time) { 3347 this.trigger('_scrollRequest', { time: time }); 3348 } 3349 }; 3350 return CalendarApi; 3351 }()); 3352 3353 var EventApi = /** @class */ (function () { 3354 // instance will be null if expressing a recurring event that has no current instances, 3355 // OR if trying to validate an incoming external event that has no dates assigned 3356 function EventApi(context, def, instance) { 3357 this._context = context; 3358 this._def = def; 3359 this._instance = instance || null; 3360 } 3361 /* 3362 TODO: make event struct more responsible for this 3363 */ 3364 EventApi.prototype.setProp = function (name, val) { 3365 var _a, _b; 3366 if (name in EVENT_DATE_REFINERS) { 3367 console.warn('Could not set date-related prop \'name\'. Use one of the date-related methods instead.'); 3368 // TODO: make proper aliasing system? 3369 } 3370 else if (name === 'id') { 3371 val = EVENT_NON_DATE_REFINERS[name](val); 3372 this.mutate({ 3373 standardProps: { publicId: val }, // hardcoded internal name 3374 }); 3375 } 3376 else if (name in EVENT_NON_DATE_REFINERS) { 3377 val = EVENT_NON_DATE_REFINERS[name](val); 3378 this.mutate({ 3379 standardProps: (_a = {}, _a[name] = val, _a), 3380 }); 3381 } 3382 else if (name in EVENT_UI_REFINERS) { 3383 var ui = EVENT_UI_REFINERS[name](val); 3384 if (name === 'color') { 3385 ui = { backgroundColor: val, borderColor: val }; 3386 } 3387 else if (name === 'editable') { 3388 ui = { startEditable: val, durationEditable: val }; 3389 } 3390 else { 3391 ui = (_b = {}, _b[name] = val, _b); 3392 } 3393 this.mutate({ 3394 standardProps: { ui: ui }, 3395 }); 3396 } 3397 else { 3398 console.warn("Could not set prop '" + name + "'. Use setExtendedProp instead."); 3399 } 3400 }; 3401 EventApi.prototype.setExtendedProp = function (name, val) { 3402 var _a; 3403 this.mutate({ 3404 extendedProps: (_a = {}, _a[name] = val, _a), 3405 }); 3406 }; 3407 EventApi.prototype.setStart = function (startInput, options) { 3408 if (options === void 0) { options = {}; } 3409 var dateEnv = this._context.dateEnv; 3410 var start = dateEnv.createMarker(startInput); 3411 if (start && this._instance) { // TODO: warning if parsed bad 3412 var instanceRange = this._instance.range; 3413 var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!? 3414 if (options.maintainDuration) { 3415 this.mutate({ datesDelta: startDelta }); 3416 } 3417 else { 3418 this.mutate({ startDelta: startDelta }); 3419 } 3420 } 3421 }; 3422 EventApi.prototype.setEnd = function (endInput, options) { 3423 if (options === void 0) { options = {}; } 3424 var dateEnv = this._context.dateEnv; 3425 var end; 3426 if (endInput != null) { 3427 end = dateEnv.createMarker(endInput); 3428 if (!end) { 3429 return; // TODO: warning if parsed bad 3430 } 3431 } 3432 if (this._instance) { 3433 if (end) { 3434 var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity); 3435 this.mutate({ endDelta: endDelta }); 3436 } 3437 else { 3438 this.mutate({ standardProps: { hasEnd: false } }); 3439 } 3440 } 3441 }; 3442 EventApi.prototype.setDates = function (startInput, endInput, options) { 3443 if (options === void 0) { options = {}; } 3444 var dateEnv = this._context.dateEnv; 3445 var standardProps = { allDay: options.allDay }; 3446 var start = dateEnv.createMarker(startInput); 3447 var end; 3448 if (!start) { 3449 return; // TODO: warning if parsed bad 3450 } 3451 if (endInput != null) { 3452 end = dateEnv.createMarker(endInput); 3453 if (!end) { // TODO: warning if parsed bad 3454 return; 3455 } 3456 } 3457 if (this._instance) { 3458 var instanceRange = this._instance.range; 3459 // when computing the diff for an event being converted to all-day, 3460 // compute diff off of the all-day values the way event-mutation does. 3461 if (options.allDay === true) { 3462 instanceRange = computeAlignedDayRange(instanceRange); 3463 } 3464 var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); 3465 if (end) { 3466 var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity); 3467 if (durationsEqual(startDelta, endDelta)) { 3468 this.mutate({ datesDelta: startDelta, standardProps: standardProps }); 3469 } 3470 else { 3471 this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps }); 3472 } 3473 } 3474 else { // means "clear the end" 3475 standardProps.hasEnd = false; 3476 this.mutate({ datesDelta: startDelta, standardProps: standardProps }); 3477 } 3478 } 3479 }; 3480 EventApi.prototype.moveStart = function (deltaInput) { 3481 var delta = createDuration(deltaInput); 3482 if (delta) { // TODO: warning if parsed bad 3483 this.mutate({ startDelta: delta }); 3484 } 3485 }; 3486 EventApi.prototype.moveEnd = function (deltaInput) { 3487 var delta = createDuration(deltaInput); 3488 if (delta) { // TODO: warning if parsed bad 3489 this.mutate({ endDelta: delta }); 3490 } 3491 }; 3492 EventApi.prototype.moveDates = function (deltaInput) { 3493 var delta = createDuration(deltaInput); 3494 if (delta) { // TODO: warning if parsed bad 3495 this.mutate({ datesDelta: delta }); 3496 } 3497 }; 3498 EventApi.prototype.setAllDay = function (allDay, options) { 3499 if (options === void 0) { options = {}; } 3500 var standardProps = { allDay: allDay }; 3501 var maintainDuration = options.maintainDuration; 3502 if (maintainDuration == null) { 3503 maintainDuration = this._context.options.allDayMaintainDuration; 3504 } 3505 if (this._def.allDay !== allDay) { 3506 standardProps.hasEnd = maintainDuration; 3507 } 3508 this.mutate({ standardProps: standardProps }); 3509 }; 3510 EventApi.prototype.formatRange = function (formatInput) { 3511 var dateEnv = this._context.dateEnv; 3512 var instance = this._instance; 3513 var formatter = createFormatter(formatInput); 3514 if (this._def.hasEnd) { 3515 return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, { 3516 forcedStartTzo: instance.forcedStartTzo, 3517 forcedEndTzo: instance.forcedEndTzo, 3518 }); 3519 } 3520 return dateEnv.format(instance.range.start, formatter, { 3521 forcedTzo: instance.forcedStartTzo, 3522 }); 3523 }; 3524 EventApi.prototype.mutate = function (mutation) { 3525 var instance = this._instance; 3526 if (instance) { 3527 var def = this._def; 3528 var context_1 = this._context; 3529 var eventStore_1 = context_1.getCurrentData().eventStore; 3530 var relevantEvents = getRelevantEvents(eventStore_1, instance.instanceId); 3531 var eventConfigBase = { 3532 '': { 3533 display: '', 3534 startEditable: true, 3535 durationEditable: true, 3536 constraints: [], 3537 overlap: null, 3538 allows: [], 3539 backgroundColor: '', 3540 borderColor: '', 3541 textColor: '', 3542 classNames: [], 3543 }, 3544 }; 3545 relevantEvents = applyMutationToEventStore(relevantEvents, eventConfigBase, mutation, context_1); 3546 var oldEvent = new EventApi(context_1, def, instance); // snapshot 3547 this._def = relevantEvents.defs[def.defId]; 3548 this._instance = relevantEvents.instances[instance.instanceId]; 3549 context_1.dispatch({ 3550 type: 'MERGE_EVENTS', 3551 eventStore: relevantEvents, 3552 }); 3553 context_1.emitter.trigger('eventChange', { 3554 oldEvent: oldEvent, 3555 event: this, 3556 relatedEvents: buildEventApis(relevantEvents, context_1, instance), 3557 revert: function () { 3558 context_1.dispatch({ 3559 type: 'RESET_EVENTS', 3560 eventStore: eventStore_1, 3561 }); 3562 }, 3563 }); 3564 } 3565 }; 3566 EventApi.prototype.remove = function () { 3567 var context = this._context; 3568 var asStore = eventApiToStore(this); 3569 context.dispatch({
3570 type: 'REMOVE_EVENTS', 3571 eventStore: asStore, 3572 }); 3573 context.emitter.trigger('eventRemove', { 3574 event: this, 3575 relatedEvents: [], 3576 revert: function () { 3577 context.dispatch({ 3578 type: 'MERGE_EVENTS', 3579 eventStore: asStore, 3580 }); 3581 }, 3582 }); 3583 }; 3584 Object.defineProperty(EventApi.prototype, "source", { 3585 get: function () { 3586 var sourceId = this._def.sourceId; 3587 if (sourceId) { 3588 return new EventSourceApi(this._context, this._context.getCurrentData().eventSources[sourceId]); 3589 } 3590 return null; 3591 }, 3592 enumerable: false, 3593 configurable: true 3594 }); 3595 Object.defineProperty(EventApi.prototype, "start", { 3596 get: function () { 3597 return this._instance ? 3598 this._context.dateEnv.toDate(this._instance.range.start) : 3599 null; 3600 }, 3601 enumerable: false, 3602 configurable: true 3603 }); 3604 Object.defineProperty(EventApi.prototype, "end", { 3605 get: function () { 3606 return (this._instance && this._def.hasEnd) ? 3607 this._context.dateEnv.toDate(this._instance.range.end) : 3608 null; 3609 }, 3610 enumerable: false, 3611 configurable: true 3612 }); 3613 Object.defineProperty(EventApi.prototype, "startStr", { 3614 get: function () { 3615 var instance = this._instance; 3616 if (instance) { 3617 return this._context.dateEnv.formatIso(instance.range.start, { 3618 omitTime: this._def.allDay, 3619 forcedTzo: instance.forcedStartTzo, 3620 }); 3621 } 3622 return ''; 3623 }, 3624 enumerable: false, 3625 configurable: true 3626 }); 3627 Object.defineProperty(EventApi.prototype, "endStr", { 3628 get: function () { 3629 var instance = this._instance; 3630 if (instance && this._def.hasEnd) { 3631 return this._context.dateEnv.formatIso(instance.range.end, { 3632 omitTime: this._def.allDay, 3633 forcedTzo: instance.forcedEndTzo, 3634 }); 3635 } 3636 return ''; 3637 }, 3638 enumerable: false, 3639 configurable: true 3640 }); 3641 Object.defineProperty(EventApi.prototype, "id", { 3642 // computable props that all access the def
3643 // TODO: find a TypeScript-compatible way to do this at scale 3644 get: function () { return this._def.publicId; }, 3645 enumerable: false, 3646 configurable: true 3647 }); 3648 Object.defineProperty(EventApi.prototype, "groupId", { 3649 get: function () { return this._def.groupId; }, 3650 enumerable: false, 3651 configurable: true 3652 }); 3653 Object.defineProperty(EventApi.prototype, "allDay", { 3654 get: function () { return this._def.allDay; }, 3655 enumerable: false, 3656 configurable: true 3657 }); 3658 Object.defineProperty(EventApi.prototype, "title", { 3659 get: function () { return this._def.title; }, 3660 enumerable: false, 3661 configurable: true 3662 }); 3663 Object.defineProperty(EventApi.prototype, "url", { 3664 get: function () { return this._def.url; }, 3665 enumerable: false, 3666 configurable: true 3667 }); 3668 Object.defineProperty(EventApi.prototype, "display", { 3669 get: function () { return this._def.ui.display || 'auto'; } // bad. just normalize the type earlier 3670 , 3671 enumerable: false, 3672 configurable: true 3673 }); 3674 Object.defineProperty(EventApi.prototype, "startEditable", { 3675 get: function () { return this._def.ui.startEditable; }, 3676 enumerable: false, 3677 configurable: true 3678 }); 3679 Object.defineProperty(EventApi.prototype, "durationEditable", { 3680 get: function () { return this._def.ui.durationEditable; }, 3681 enumerable: false, 3682 configurable: true 3683 }); 3684 Object.defineProperty(EventApi.prototype, "constraint", { 3685 get: function () { return this._def.ui.constraints[0] || null; }, 3686 enumerable: false, 3687 configurable: true 3688 }); 3689 Object.defineProperty(EventApi.prototype, "overlap", { 3690 get: function () { return this._def.ui.overlap; }, 3691 enumerable: false, 3692 configurable: true 3693 }); 3694 Object.defineProperty(EventApi.prototype, "allow", { 3695 get: function () { return this._def.ui.allows[0] || null; }, 3696 enumerable: false, 3697 configurable: true 3698 }); 3699 Object.defineProperty(EventApi.prototype, "backgroundColor", { 3700 get: function () { return this._def.ui.backgroundColor; }, 3701 enumerable: false, 3702 configurable: true 3703 }); 3704 Object.defineProperty(EventApi.prototype, "borderColor", { 3705 get: function () { return this._def.ui.borderColor; }, 3706 enumerable: false, 3707 configurable: true 3708 }); 3709 Object.defineProperty(EventApi.prototype, "textColor", { 3710 get: function () { return this._def.ui.textColor; }, 3711 enumerable: false, 3712 configurable: true 3713 }); 3714 Object.defineProperty(EventApi.prototype, "classNames", { 3715 // NOTE: user can't modify these because Object.freeze was called in event-def parsing 3716 get: function () { return this._def.ui.classNames; }, 3717 enumerable: false, 3718 configurable: true 3719 }); 3720 Object.defineProperty(EventApi.prototype, "extendedProps", { 3721 get: function () { return this._def.extendedProps; }, 3722 enumerable: false, 3723 configurable: true 3724 }); 3725 EventApi.prototype.toPlainObject = function (settings) { 3726 if (settings === void 0) { settings = {}; } 3727 var def = this._def; 3728 var ui = def.ui; 3729 var _a = this, startStr = _a.startStr, endStr = _a.endStr; 3730 var res = {}; 3731 if (def.title) { 3732 res.title = def.title; 3733 } 3734 if (startStr) { 3735 res.start = startStr; 3736 } 3737 if (endStr) { 3738 res.end = endStr; 3739 } 3740 if (def.publicId) { 3741 res.id = def.publicId; 3742 } 3743 if (def.groupId) { 3744 res.groupId = def.groupId; 3745 } 3746 if (def.url) { 3747 res.url = def.url; 3748 } 3749 if (ui.display && ui.display !== 'auto') { 3750 res.display = ui.display; 3751 } 3752 // TODO: what about recurring-event properties??? 3753 // TODO: include startEditable/durationEditable/constraint/overlap/allow 3754 if (settings.collapseColor && ui.backgroundColor && ui.backgroundColor === ui.borderColor) { 3755 res.color = ui.backgroundColor; 3756 } 3757 else { 3758 if (ui.backgroundColor) { 3759 res.backgroundColor = ui.backgroundColor; 3760 } 3761 if (ui.borderColor) { 3762 res.borderColor = ui.borderColor; 3763 } 3764 } 3765 if (ui.textColor) { 3766 res.textColor = ui.textColor; 3767 } 3768 if (ui.classNames.length) { 3769 res.classNames = ui.classNames; 3770 } 3771 if (Object.keys(def.extendedProps).length) { 3772 if (settings.collapseExtendedProps) { 3773 __assign(res, def.extendedProps); 3774 } 3775 else { 3776 res.extendedProps = def.extendedProps; 3777 } 3778 } 3779 return res; 3780 }; 3781 EventApi.prototype.toJSON = function () { 3782 return this.toPlainObject(); 3783 }; 3784 return EventApi; 3785 }()); 3786 function eventApiToStore(eventApi) { 3787 var _a, _b; 3788 var def = eventApi._def; 3789 var instance = eventApi._instance; 3790 return { 3791 defs: (_a = {}, _a[def.defId] = def, _a), 3792 instances: instance 3793 ? (_b = {}, _b[instance.instanceId] = instance, _b) : {}, 3794 }; 3795 } 3796 function buildEventApis(eventStore, context, excludeInstance) { 3797 var defs = eventStore.defs, instances = eventStore.instances; 3798 var eventApis = []; 3799 var excludeInstanceId = excludeInstance ? excludeInstance.instanceId : ''; 3800 for (var id in instances) { 3801 var instance = instances[id]; 3802 var def = defs[instance.defId]; 3803 if (instance.instanceId !== excludeInstanceId) { 3804 eventApis.push(new EventApi(context, def, instance)); 3805 } 3806 } 3807 return eventApis; 3808 } 3809 3810 var calendarSystemClassMap = {}; 3811 function registerCalendarSystem(name, theClass) { 3812 calendarSystemClassMap[name] = theClass; 3813 } 3814 function createCalendarSystem(name) { 3815 return new calendarSystemClassMap[name](); 3816 } 3817 var GregorianCalendarSystem = /** @class */ (function () { 3818 function GregorianCalendarSystem() { 3819 } 3820 GregorianCalendarSystem.prototype.getMarkerYear = function (d) { 3821 return d.getUTCFullYear(); 3822 }; 3823 GregorianCalendarSystem.prototype.getMarkerMonth = function (d) { 3824 return d.getUTCMonth(); 3825 }; 3826 GregorianCalendarSystem.prototype.getMarkerDay = function (d) { 3827 return d.getUTCDate(); 3828 }; 3829 GregorianCalendarSystem.prototype.arrayToMarker = function (arr) { 3830 return arrayToUtcDate(arr); 3831 }; 3832 GregorianCalendarSystem.prototype.markerToArray = function (marker) { 3833 return dateToUtcArray(marker); 3834 }; 3835 return GregorianCalendarSystem; 3836 }()); 3837 registerCalendarSystem('gregory', GregorianCalendarSystem); 3838 3839 var ISO_RE = /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/; 3840 function parse(str) { 3841 var m = ISO_RE.exec(str); 3842 if (m) { 3843 var 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)); 3844 if (isValidDate(marker)) { 3845 var timeZoneOffset = null; 3846 if (m[13]) { 3847 timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 + 3848 Number(m[18] || 0)); 3849 } 3850 return { 3851 marker: marker, 3852 isTimeUnspecified: !m[6], 3853 timeZoneOffset: timeZoneOffset, 3854 }; 3855 } 3856 } 3857 return null; 3858 } 3859 3860 var DateEnv = /** @class */ (function () { 3861 function DateEnv(settings) { 3862 var timeZone = this.timeZone = settings.timeZone; 3863 var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC'; 3864 if (settings.namedTimeZoneImpl && isNamedTimeZone) { 3865 this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone); 3866 } 3867 this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl); 3868 this.calendarSystem = createCalendarSystem(settings.calendarSystem); 3869 this.locale = settings.locale; 3870 this.weekDow = settings.locale.week.dow; 3871 this.weekDoy = settings.locale.week.doy; 3872 if (settings.weekNumberCalculation === 'ISO') { 3873 this.weekDow = 1; 3874 this.weekDoy = 4; 3875 } 3876 if (typeof settings.firstDay === 'number') { 3877 this.weekDow = settings.firstDay; 3878 } 3879 if (typeof settings.weekNumberCalculation === 'function') {
vendor: 9,750 bytes, lines 3880-4114
3880 this.weekNumberFunc = settings.weekNumberCalculation; 3881 } 3882 this.weekText = settings.weekText != null ? settings.weekText : settings.locale.options.weekText; 3883 this.weekTextLong = (settings.weekTextLong != null ? settings.weekTextLong : settings.locale.options.weekTextLong) || this.weekText; 3884 this.cmdFormatter = settings.cmdFormatter; 3885 this.defaultSeparator = settings.defaultSeparator; 3886 } 3887 // Creating / Parsing 3888 DateEnv.prototype.createMarker = function (input) { 3889 var meta = this.createMarkerMeta(input); 3890 if (meta === null) { 3891 return null; 3892 } 3893 return meta.marker; 3894 }; 3895 DateEnv.prototype.createNowMarker = function () { 3896 if (this.canComputeOffset) { 3897 return this.timestampToMarker(new Date().valueOf()); 3898 } 3899 // if we can't compute the current date val for a timezone, 3900 // better to give the current local date vals than UTC 3901 return arrayToUtcDate(dateToLocalArray(new Date())); 3902 }; 3903 DateEnv.prototype.createMarkerMeta = function (input) { 3904 if (typeof input === 'string') { 3905 return this.parse(input); 3906 } 3907 var marker = null; 3908 if (typeof input === 'number') { 3909 marker = this.timestampToMarker(input); 3910 } 3911 else if (input instanceof Date) { 3912 input = input.valueOf(); 3913 if (!isNaN(input)) { 3914 marker = this.timestampToMarker(input); 3915 } 3916 } 3917 else if (Array.isArray(input)) { 3918 marker = arrayToUtcDate(input); 3919 } 3920 if (marker === null || !isValidDate(marker)) { 3921 return null; 3922 } 3923 return { marker: marker, isTimeUnspecified: false, forcedTzo: null }; 3924 }; 3925 DateEnv.prototype.parse = function (s) { 3926 var parts = parse(s); 3927 if (parts === null) { 3928 return null; 3929 } 3930 var marker = parts.marker; 3931 var forcedTzo = null; 3932 if (parts.timeZoneOffset !== null) { 3933 if (this.canComputeOffset) { 3934 marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000); 3935 } 3936 else { 3937 forcedTzo = parts.timeZoneOffset; 3938 } 3939 } 3940 return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo }; 3941 }; 3942 // Accessors 3943 DateEnv.prototype.getYear = function (marker) { 3944 return this.calendarSystem.getMarkerYear(marker); 3945 }; 3946 DateEnv.prototype.getMonth = function (marker) { 3947 return this.calendarSystem.getMarkerMonth(marker); 3948 }; 3949 // Adding / Subtracting 3950 DateEnv.prototype.add = function (marker, dur) { 3951 var a = this.calendarSystem.markerToArray(marker); 3952 a[0] += dur.years; 3953 a[1] += dur.months; 3954 a[2] += dur.days; 3955 a[6] += dur.milliseconds; 3956 return this.calendarSystem.arrayToMarker(a); 3957 }; 3958 DateEnv.prototype.subtract = function (marker, dur) { 3959 var a = this.calendarSystem.markerToArray(marker); 3960 a[0] -= dur.years; 3961 a[1] -= dur.months; 3962 a[2] -= dur.days; 3963 a[6] -= dur.milliseconds; 3964 return this.calendarSystem.arrayToMarker(a); 3965 }; 3966 DateEnv.prototype.addYears = function (marker, n) { 3967 var a = this.calendarSystem.markerToArray(marker); 3968 a[0] += n; 3969 return this.calendarSystem.arrayToMarker(a); 3970 }; 3971 DateEnv.prototype.addMonths = function (marker, n) { 3972 var a = this.calendarSystem.markerToArray(marker); 3973 a[1] += n; 3974 return this.calendarSystem.arrayToMarker(a); 3975 }; 3976 // Diffing Whole Units 3977 DateEnv.prototype.diffWholeYears = function (m0, m1) { 3978 var calendarSystem = this.calendarSystem; 3979 if (timeAsMs(m0) === timeAsMs(m1) && 3980 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) && 3981 calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) { 3982 return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0); 3983 } 3984 return null; 3985 }; 3986 DateEnv.prototype.diffWholeMonths = function (m0, m1) { 3987 var calendarSystem = this.calendarSystem; 3988 if (timeAsMs(m0) === timeAsMs(m1) && 3989 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) { 3990 return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) + 3991 (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12; 3992 } 3993 return null; 3994 }; 3995 // Range / Duration 3996 DateEnv.prototype.greatestWholeUnit = function (m0, m1) { 3997 var n = this.diffWholeYears(m0, m1); 3998 if (n !== null) { 3999 return { unit: 'year', value: n }; 4000 } 4001 n = this.diffWholeMonths(m0, m1); 4002 if (n !== null) { 4003 return { unit: 'month', value: n }; 4004 } 4005 n = diffWholeWeeks(m0, m1); 4006 if (n !== null) { 4007 return { unit: 'week', value: n }; 4008 } 4009 n = diffWholeDays(m0, m1); 4010 if (n !== null) { 4011 return { unit: 'day', value: n }; 4012 } 4013 n = diffHours(m0, m1); 4014 if (isInt(n)) { 4015 return { unit: 'hour', value: n }; 4016 } 4017 n = diffMinutes(m0, m1); 4018 if (isInt(n)) { 4019 return { unit: 'minute', value: n }; 4020 } 4021 n = diffSeconds(m0, m1); 4022 if (isInt(n)) { 4023 return { unit: 'second', value: n }; 4024 } 4025 return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() }; 4026 }; 4027 DateEnv.prototype.countDurationsBetween = function (m0, m1, d) { 4028 // TODO: can use greatestWholeUnit 4029 var diff; 4030 if (d.years) { 4031 diff = this.diffWholeYears(m0, m1); 4032 if (diff !== null) { 4033 return diff / asRoughYears(d); 4034 } 4035 } 4036 if (d.months) { 4037 diff = this.diffWholeMonths(m0, m1); 4038 if (diff !== null) { 4039 return diff / asRoughMonths(d); 4040 } 4041 } 4042 if (d.days) { 4043 diff = diffWholeDays(m0, m1); 4044 if (diff !== null) { 4045 return diff / asRoughDays(d); 4046 } 4047 } 4048 return (m1.valueOf() - m0.valueOf()) / asRoughMs(d); 4049 }; 4050 // Start-Of 4051 // these DON'T return zoned-dates. only UTC start-of dates 4052 DateEnv.prototype.startOf = function (m, unit) { 4053 if (unit === 'year') { 4054 return this.startOfYear(m); 4055 } 4056 if (unit === 'month') { 4057 return this.startOfMonth(m); 4058 } 4059 if (unit === 'week') { 4060 return this.startOfWeek(m); 4061 } 4062 if (unit === 'day') { 4063 return startOfDay(m); 4064 } 4065 if (unit === 'hour') { 4066 return startOfHour(m); 4067 } 4068 if (unit === 'minute') { 4069 return startOfMinute(m); 4070 } 4071 if (unit === 'second') { 4072 return startOfSecond(m); 4073 } 4074 return null; 4075 }; 4076 DateEnv.prototype.startOfYear = function (m) { 4077 return this.calendarSystem.arrayToMarker([ 4078 this.calendarSystem.getMarkerYear(m), 4079 ]); 4080 }; 4081 DateEnv.prototype.startOfMonth = function (m) { 4082 return this.calendarSystem.arrayToMarker([ 4083 this.calendarSystem.getMarkerYear(m), 4084 this.calendarSystem.getMarkerMonth(m), 4085 ]); 4086 }; 4087 DateEnv.prototype.startOfWeek = function (m) { 4088 return this.calendarSystem.arrayToMarker([ 4089 this.calendarSystem.getMarkerYear(m), 4090 this.calendarSystem.getMarkerMonth(m), 4091 m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7), 4092 ]); 4093 }; 4094 // Week Number 4095 DateEnv.prototype.computeWeekNumber = function (marker) { 4096 if (this.weekNumberFunc) { 4097 return this.weekNumberFunc(this.toDate(marker)); 4098 } 4099 return weekOfYear(marker, this.weekDow, this.weekDoy); 4100 }; 4101 // TODO: choke on timeZoneName: long 4102 DateEnv.prototype.format = function (marker, formatter, dateOptions) { 4103 if (dateOptions === void 0) { dateOptions = {}; } 4104 return formatter.format({ 4105 marker: marker, 4106 timeZoneOffset: dateOptions.forcedTzo != null ? 4107 dateOptions.forcedTzo : 4108 this.offsetForMarker(marker), 4109 }, this); 4110 }; 4111 DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) { 4112 if (dateOptions === void 0) { dateOptions = {}; } 4113 if (dateOptions.isEndExclusive) { 4114 end = addMs(end, -1);
4115 } 4116 return formatter.formatRange({ 4117 marker: start, 4118 timeZoneOffset: dateOptions.forcedStartTzo != null ? 4119 dateOptions.forcedStartTzo : 4120 this.offsetForMarker(start), 4121 }, { 4122 marker: end, 4123 timeZoneOffset: dateOptions.forcedEndTzo != null ? 4124 dateOptions.forcedEndTzo : 4125 this.offsetForMarker(end), 4126 }, this, dateOptions.defaultSeparator); 4127 }; 4128 /* 4129 DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that, 4130 might as well use buildIsoString or some other util directly 4131 */ 4132 DateEnv.prototype.formatIso = function (marker, extraOptions) { 4133 if (extraOptions === void 0) { extraOptions = {}; } 4134 var timeZoneOffset = null; 4135 if (!extraOptions.omitTimeZoneOffset) { 4136 if (extraOptions.forcedTzo != null) { 4137 timeZoneOffset = extraOptions.forcedTzo; 4138 } 4139 else { 4140 timeZoneOffset = this.offsetForMarker(marker); 4141 } 4142 } 4143 return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime); 4144 }; 4145 // TimeZone 4146 DateEnv.prototype.timestampToMarker = function (ms) { 4147 if (this.timeZone === 'local') { 4148 return arrayToUtcDate(dateToLocalArray(new Date(ms))); 4149 } 4150 if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) { 4151 return new Date(ms); 4152 } 4153 return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms)); 4154 }; 4155 DateEnv.prototype.offsetForMarker = function (m) { 4156 if (this.timeZone === 'local') { 4157 return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset 4158 } 4159 if (this.timeZone === 'UTC') { 4160 return 0; 4161 } 4162 if (this.namedTimeZoneImpl) { 4163 return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)); 4164 } 4165 return null; 4166 }; 4167 // Conversion 4168 DateEnv.prototype.toDate = function (m, forcedTzo) { 4169 if (this.timeZone === 'local') { 4170 return arrayToLocalDate(dateToUtcArray(m)); 4171 } 4172 if (this.timeZone === 'UTC') { 4173 return new Date(m.valueOf()); // make sure it's a copy 4174 } 4175 if (!this.namedTimeZoneImpl) { 4176 return new Date(m.valueOf() - (forcedTzo || 0)); 4177 } 4178 return new Date(m.valueOf() - 4179 this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60); 4180 }; 4181 return DateEnv; 4182 }()); 4183 4184 var globalLocales = []; 4185 4186 var MINIMAL_RAW_EN_LOCALE = { 4187 code: 'en', 4188 week: { 4189 dow: 0, 4190 doy: 4, // 4 days need to be within the year to be considered the first week 4191 }, 4192 direction: 'ltr', 4193 buttonText: { 4194 prev: 'prev', 4195 next: 'next', 4196 prevYear: 'prev year', 4197 nextYear: 'next year', 4198 year: 'year', 4199 today: 'today', 4200 month: 'month', 4201 week: 'week', 4202 day: 'day', 4203 list: 'list', 4204 }, 4205 weekText: 'W', 4206 weekTextLong: 'Week', 4207 closeHint: 'Close', 4208 timeHint: 'Time', 4209 eventHint: 'Event', 4210 allDayText: 'all-day', 4211 moreLinkText: 'more', 4212 noEventsText: 'No events to display', 4213 }; 4214 var RAW_EN_LOCALE = __assign(__assign({}, MINIMAL_RAW_EN_LOCALE), { 4215 // Includes things we don't want other locales to inherit, 4216 // things that derive from other translatable strings. 4217 buttonHints: { 4218 prev: 'Previous $0', 4219 next: 'Next $0', 4220 today: function (buttonText, unit) { 4221 return (unit === 'day') 4222 ? 'Today' 4223 : "This " + buttonText; 4224 }, 4225 }, viewHint: '$0 view', navLinkHint: 'Go to $0', moreLinkHint: function (eventCnt) { 4226 return "Show " + eventCnt + " more event" + (eventCnt === 1 ? '' : 's'); 4227 } }); 4228 function organizeRawLocales(explicitRawLocales) { 4229 var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en'; 4230 var allRawLocales = globalLocales.concat(explicitRawLocales); 4231 var rawLocaleMap = { 4232 en: RAW_EN_LOCALE, 4233 }; 4234 for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) { 4235 var rawLocale = allRawLocales_1[_i]; 4236 rawLocaleMap[rawLocale.code] = rawLocale; 4237 } 4238 return { 4239 map: rawLocaleMap, 4240 defaultCode: defaultCode, 4241 }; 4242 } 4243 function buildLocale(inputSingular, available) { 4244 if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) { 4245 return parseLocale(inputSingular.code, [inputSingular.code], inputSingular); 4246 } 4247 return queryLocale(inputSingular, available); 4248 } 4249 function queryLocale(codeArg, available) { 4250 var codes = [].concat(codeArg || []); // will convert to array 4251 var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE; 4252 return parseLocale(codeArg, codes, raw); 4253 } 4254 function queryRawLocale(codes, available) { 4255 for (var i = 0; i < codes.length; i += 1) { 4256 var parts = codes[i].toLocaleLowerCase().split('-'); 4257 for (var j = parts.length; j > 0; j -= 1) { 4258 var simpleId = parts.slice(0, j).join('-'); 4259 if (available[simpleId]) { 4260 return available[simpleId]; 4261 } 4262 } 4263 } 4264 return null; 4265 } 4266 function parseLocale(codeArg, codes, raw) { 4267 var merged = mergeProps([MINIMAL_RAW_EN_LOCALE, raw], ['buttonText']); 4268 delete merged.code; // don't want this part of the options 4269 var week = merged.week; 4270 delete merged.week; 4271 return { 4272 codeArg: codeArg, 4273 codes: codes, 4274 week: week, 4275 simpleNumberFormat: new Intl.NumberFormat(codeArg), 4276 options: merged, 4277 }; 4278 } 4279 4280 function formatDate(dateInput, options) { 4281 if (options === void 0) { options = {}; } 4282 var dateEnv = buildDateEnv$1(options); 4283 var formatter = createFormatter(options); 4284 var dateMeta = dateEnv.createMarkerMeta(dateInput); 4285 if (!dateMeta) { // TODO: warning? 4286 return ''; 4287 } 4288 return dateEnv.format(dateMeta.marker, formatter, { 4289 forcedTzo: dateMeta.forcedTzo, 4290 }); 4291 } 4292 function formatRange(startInput, endInput, options) { 4293 var dateEnv = buildDateEnv$1(typeof options === 'object' && options ? options : {}); // pass in if non-null object 4294 var formatter = createFormatter(options); 4295 var startMeta = dateEnv.createMarkerMeta(startInput); 4296 var endMeta = dateEnv.createMarkerMeta(endInput); 4297 if (!startMeta || !endMeta) { // TODO: warning? 4298 return ''; 4299 } 4300 return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, { 4301 forcedStartTzo: startMeta.forcedTzo, 4302 forcedEndTzo: endMeta.forcedTzo, 4303 isEndExclusive: options.isEndExclusive, 4304 defaultSeparator: BASE_OPTION_DEFAULTS.defaultRangeSeparator, 4305 }); 4306 } 4307 // TODO: more DRY and optimized 4308 function buildDateEnv$1(settings) { 4309 var locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere 4310 return new DateEnv(__assign(__assign({ timeZone: BASE_OPTION_DEFAULTS.timeZone, calendarSystem: 'gregory' }, settings), { locale: locale })); 4311 } 4312 4313 var DEF_DEFAULTS = { 4314 startTime: '09:00', 4315 endTime: '17:00', 4316 daysOfWeek: [1, 2, 3, 4, 5], 4317 display: 'inverse-background', 4318 classNames: 'fc-non-business', 4319 groupId: '_businessHours', // so multiple defs get grouped 4320 }; 4321 /* 4322 TODO: pass around as EventDefHash!!! 4323 */ 4324 function parseBusinessHours(input, context) { 4325 return parseEvents(refineInputs(input), null, context); 4326 } 4327 function refineInputs(input) { 4328 var rawDefs; 4329 if (input === true) { 4330 rawDefs = [{}]; // will get DEF_DEFAULTS verbatim 4331 } 4332 else if (Array.isArray(input)) { 4333 // if specifying an array, every sub-definition NEEDS a day-of-week 4334 rawDefs = input.filter(function (rawDef) { return rawDef.daysOfWeek; }); 4335 } 4336 else if (typeof input === 'object' && input) { // non-null object 4337 rawDefs = [input]; 4338 } 4339 else { // is probably false 4340 rawDefs = []; 4341 } 4342 rawDefs = rawDefs.map(function (rawDef) { return (__assign(__assign({}, DEF_DEFAULTS), rawDef)); }); 4343 return rawDefs; 4344 } 4345 4346 function pointInsideRect(point, rect) { 4347 return point.left >= rect.left && 4348 point.left < rect.right && 4349 point.top >
4349= rect.top && 4350 point.top < rect.bottom; 4351 } 4352 // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false 4353 function intersectRects(rect1, rect2) { 4354 var res = { 4355 left: Math.max(rect1.left, rect2.left), 4356 right: Math.min(rect1.right, rect2.right), 4357 top: Math.max(rect1.top, rect2.top), 4358 bottom: Math.min(rect1.bottom, rect2.bottom), 4359 }; 4360 if (res.left < res.right && res.top < res.bottom) { 4361 return res; 4362 } 4363 return false; 4364 } 4365 function translateRect(rect, deltaX, deltaY) { 4366 return { 4367 left: rect.left + deltaX, 4368 right: rect.right + deltaX, 4369 top: rect.top + deltaY, 4370 bottom: rect.bottom + deltaY, 4371 }; 4372 } 4373 // Returns a new point that will have been moved to reside within the given rectangle 4374 function constrainPoint(point, rect) { 4375 return { 4376 left: Math.min(Math.max(point.left, rect.left), rect.right), 4377 top: Math.min(Math.max(point.top, rect.top), rect.bottom), 4378 }; 4379 } 4380 // Returns a point that is the center of the given rectangle 4381 function getRectCenter(rect) { 4382 return { 4383 left: (rect.left + rect.right) / 2, 4384 top: (rect.top + rect.bottom) / 2, 4385 }; 4386 } 4387 // Subtracts point2's coordinates from point1's coordinates, returning a delta 4388 function diffPoints(point1, point2) { 4389 return { 4390 left: point1.left - point2.left, 4391 top: point1.top - point2.top, 4392 }; 4393 } 4394 4395 var canVGrowWithinCell; 4396 function getCanVGrowWithinCell() { 4397 if (canVGrowWithinCell == null) { 4398 canVGrowWithinCell = computeCanVGrowWithinCell(); 4399 } 4400 return canVGrowWithinCell; 4401 } 4402 function computeCanVGrowWithinCell() { 4403 // for SSR, because this function is call immediately at top-level 4404 // TODO: just make this logic execute top-level, immediately, instead of doing lazily 4405 if (typeof document === 'undefined') { 4406 return true; 4407 } 4408 var el = document.createElement('div'); 4409 el.style.position = 'absolute'; 4410 el.style.top = '0px'; 4411 el.style.left = '0px'; 4412 el.innerHTML = '<table><tr><td><div></div></td></tr></table>'; 4413 el.querySelector('table').style.height = '100px'; 4414 el.querySelector('div').style.height = '100%'; 4415 document.body.appendChild(el); 4416 var div = el.querySelector('div'); 4417 var possible = div.offsetHeight > 0; 4418 document.body.removeChild(el); 4419 return possible; 4420 } 4421 4422 var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere 4423 var Splitter = /** @class */ (function () { 4424 function Splitter() { 4425 this.getKeysForEventDefs = memoize(this._getKeysForEventDefs); 4426 this.splitDateSelection = memoize(this._splitDateSpan); 4427 this.splitEventStore = memoize(this._splitEventStore); 4428 this.splitIndividualUi = memoize(this._splitIndividualUi); 4429 this.splitEventDrag = memoize(this._splitInteraction); 4430 this.splitEventResize = memoize(this._splitInteraction); 4431 this.eventUiBuilders = {}; // TODO: typescript protection 4432 } 4433 Splitter.prototype.splitProps = function (props) { 4434 var _this = this; 4435 var keyInfos = this.getKeyInfo(props); 4436 var defKeys = this.getKeysForEventDefs(props.eventStore); 4437 var dateSelections = this.splitDateSelection(props.dateSelection); 4438 var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases* 4439 var eventStores = this.splitEventStore(props.eventStore, defKeys); 4440 var eventDrags = this.splitEventDrag(props.eventDrag); 4441 var eventResizes = this.splitEventResize(props.eventResize); 4442 var splitProps = {}; 4443 this.eventUiBuilders = mapHash(keyInfos, function (info, key) { return _this.eventUiBuilders[key] || memoize(buildEventUiForKey); }); 4444 for (var key in keyInfos) { 4445 var keyInfo = keyInfos[key]; 4446 var eventStore = eventStores[key] || EMPTY_EVENT_STORE; 4447 var buildEventUi = this.eventUiBuilders[key]; 4448 splitProps[key] = { 4449 businessHours: keyInfo.businessHours || props.businessHours, 4450 dateSelection: dateSelections[key] || null, 4451 eventStore: eventStore, 4452 eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]), 4453 eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '', 4454 eventDrag: eventDrags[key] || null, 4455 eventResize: eventResizes[key] || null, 4456 }; 4457 } 4458 return splitProps; 4459 }; 4460 Splitter.prototype._splitDateSpan = function (dateSpan) { 4461 var dateSpans = {}; 4462 if (dateSpan) {
4463 var keys = this.getKeysForDateSpan(dateSpan); 4464 for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { 4465 var key = keys_1[_i]; 4466 dateSpans[key] = dateSpan; 4467 } 4468 } 4469 return dateSpans; 4470 }; 4471 Splitter.prototype._getKeysForEventDefs = function (eventStore) { 4472 var _this = this; 4473 return mapHash(eventStore.defs, function (eventDef) { return _this.getKeysForEventDef(eventDef); }); 4474 }; 4475 Splitter.prototype._splitEventStore = function (eventStore, defKeys) { 4476 var defs = eventStore.defs, instances = eventStore.instances; 4477 var splitStores = {}; 4478 for (var defId in defs) { 4479 for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) { 4480 var key = _a[_i]; 4481 if (!splitStores[key]) { 4482 splitStores[key] = createEmptyEventStore(); 4483 } 4484 splitStores[key].defs[defId] = defs[defId]; 4485 } 4486 } 4487 for (var instanceId in instances) { 4488 var instance = instances[instanceId]; 4489 for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) { 4490 var key = _c[_b]; 4491 if (splitStores[key]) { // must have already been created 4492 splitStores[key].instances[instanceId] = instance; 4493 } 4494 } 4495 } 4496 return splitStores; 4497 }; 4498 Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) { 4499 var splitHashes = {}; 4500 for (var defId in eventUiBases) { 4501 if (defId) { // not the '' key 4502 for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) { 4503 var key = _a[_i]; 4504 if (!splitHashes[key]) { 4505 splitHashes[key] = {}; 4506 } 4507 splitHashes[key][defId] = eventUiBases[defId]; 4508 } 4509 } 4510 } 4511 return splitHashes; 4512 }; 4513 Splitter.prototype._splitInteraction = function (interaction) { 4514 var splitStates = {}; 4515 if (interaction) { 4516 var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents)); 4517 // can't rely on defKeys because event data is mutated 4518 var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents); 4519 var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId); 4520 var populate = function (key) { 4521 if (!splitStates[key]) { 4522 splitStates[key] = { 4523 affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE, 4524 mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE, 4525 isEvent: interaction.isEvent, 4526 }; 4527 } 4528 }; 4529 for (var key in affectedStores_1) { 4530 populate(key); 4531 } 4532 for (var key in mutatedStores_1) { 4533 populate(key); 4534 } 4535 } 4536 return splitStates; 4537 }; 4538 return Splitter; 4539 }()); 4540 function buildEventUiForKey(allUi, eventUiForKey, individualUi) { 4541 var baseParts = []; 4542 if (allUi) { 4543 baseParts.push(allUi); 4544 } 4545 if (eventUiForKey) { 4546 baseParts.push(eventUiForKey); 4547 } 4548 var stuff = { 4549 '': combineEventUis(baseParts), 4550 }; 4551 if (individualUi) { 4552 __assign(stuff, individualUi); 4553 } 4554 return stuff; 4555 } 4556 4557 function getDateMeta(date, todayRange, nowDate, dateProfile) { 4558 return { 4559 dow: date.getUTCDay(), 4560 isDisabled: Boolean(dateProfile && !rangeContainsMarker(dateProfile.activeRange, date)), 4561 isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)), 4562 isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)), 4563 isPast: Boolean(nowDate ? (date < nowDate) : todayRange ? (date < todayRange.start) : false), 4564 isFuture: Boolean(nowDate ? (date > nowDate) : todayRange ? (date >= todayRange.end) : false), 4565 }; 4566 } 4567 function getDayClassNames(meta, theme) { 4568 var classNames = [ 4569 'fc-day',
4570 "fc-day-" + DAY_IDS[meta.dow], 4571 ]; 4572 if (meta.isDisabled) { 4573 classNames.push('fc-day-disabled'); 4574 } 4575 else { 4576 if (meta.isToday) { 4577 classNames.push('fc-day-today'); 4578 classNames.push(theme.getClass('today')); 4579 } 4580 if (meta.isPast) { 4581 classNames.push('fc-day-past'); 4582 } 4583 if (meta.isFuture) { 4584 classNames.push('fc-day-future'); 4585 } 4586 if (meta.isOther) { 4587 classNames.push('fc-day-other'); 4588 } 4589 } 4590 return classNames; 4591 } 4592 function getSlotClassNames(meta, theme) { 4593 var classNames = [ 4594 'fc-slot', 4595 "fc-slot-" + DAY_IDS[meta.dow], 4596 ]; 4597 if (meta.isDisabled) { 4598 classNames.push('fc-slot-disabled'); 4599 } 4600 else { 4601 if (meta.isToday) { 4602 classNames.push('fc-slot-today'); 4603 classNames.push(theme.getClass('today')); 4604 } 4605 if (meta.isPast) { 4606 classNames.push('fc-slot-past'); 4607 } 4608 if (meta.isFuture) { 4609 classNames.push('fc-slot-future'); 4610 } 4611 } 4612 return classNames; 4613 } 4614 4615 var DAY_FORMAT = createFormatter({ year: 'numeric', month: 'long', day: 'numeric' }); 4616 var WEEK_FORMAT = createFormatter({ week: 'long' }); 4617 function buildNavLinkAttrs(context, dateMarker, viewType, isTabbable) { 4618 if (viewType === void 0) { viewType = 'day'; } 4619 if (isTabbable === void 0) { isTabbable = true; } 4620 var dateEnv = context.dateEnv, options = context.options, calendarApi = context.calendarApi; 4621 var dateStr = dateEnv.format(dateMarker, viewType === 'week' ? WEEK_FORMAT : DAY_FORMAT); 4622 if (options.navLinks) { 4623 var zonedDate = dateEnv.toDate(dateMarker); 4624 var handleInteraction = function (ev) { 4625 var customAction = viewType === 'day' ? options.navLinkDayClick : 4626 viewType === 'week' ? options.navLinkWeekClick : null; 4627 if (typeof customAction === 'function') { 4628 customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev); 4629 } 4630 else { 4631 if (typeof customAction === 'string') { 4632 viewType = customAction; 4633 } 4634 calendarApi.zoomTo(dateMarker, viewType); 4635 } 4636 }; 4637 return __assign({ title: formatWithOrdinals(options.navLinkHint, [dateStr, zonedDate], dateStr), 'data-navlink': '' }, (isTabbable 4638 ? createAriaClickAttrs(handleInteraction) 4639 : { onClick: handleInteraction })); 4640 } 4641 return { 'aria-label': dateStr }; 4642 } 4643 4644 var _isRtlScrollbarOnLeft = null; 4645 function getIsRtlScrollbarOnLeft() { 4646 if (_isRtlScrollbarOnLeft === null) { 4647 _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft(); 4648 } 4649 return _isRtlScrollbarOnLeft; 4650 } 4651 function computeIsRtlScrollbarOnLeft() { 4652 var outerEl = document.createElement('div'); 4653 applyStyle(outerEl, { 4654 position: 'absolute', 4655 top: -1000, 4656 left: 0, 4657 border: 0, 4658 padding: 0, 4659 overflow: 'scroll', 4660 direction: 'rtl', 4661 }); 4662 outerEl.innerHTML = '<div></div>'; 4663 document.body.appendChild(outerEl); 4664 var innerEl = outerEl.firstChild; 4665 var res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left; 4666 removeElement(outerEl); 4667 return res; 4668 } 4669 4670 var _scrollbarWidths; 4671 function getScrollbarWidths() { 4672 if (!_scrollbarWidths) { 4673 _scrollbarWidths = computeScrollbarWidths(); 4674 } 4675 return _scrollbarWidths; 4676 } 4677 function computeScrollbarWidths() { 4678 var el = document.createElement('div'); 4679 el.style.overflow = 'scroll'; 4680 el.style.position = 'absolute'; 4681 el.style.top = '-9999px'; 4682 el.style.left = '-9999px'; 4683 document.body.appendChild(el); 4684 var res = computeScrollbarWidthsForEl(el); 4685 document.body.removeChild(el); 4686 return res; 4687 } 4688 // WARNING: will include border 4689 function computeScrollbarWidthsForEl(el) { 4690 return { 4691 x: el.offsetHeight - el.clientHeight, 4692 y: el.offsetWidth - el.clientWidth, 4693 }; 4694 } 4695 4696 function computeEdges(el, getPadding) { 4697 if (getPadding === void 0) { getPadding = false; } 4698 var computedStyle = window.getComputedStyle(el); 4699 var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0; 4700 var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0; 4701 var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0; 4702 var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
4703 var badScrollbarWidths = computeScrollbarWidthsForEl(el); // includes border! 4704 var scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight; 4705 var scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom; 4706 var res = { 4707 borderLeft: borderLeft, 4708 borderRight: borderRight, 4709 borderTop: borderTop, 4710 borderBottom: borderBottom, 4711 scrollbarBottom: scrollbarBottom, 4712 scrollbarLeft: 0, 4713 scrollbarRight: 0, 4714 }; 4715 if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side? 4716 res.scrollbarLeft = scrollbarLeftRight; 4717 } 4718 else { 4719 res.scrollbarRight = scrollbarLeftRight; 4720 } 4721 if (getPadding) { 4722 res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0; 4723 res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0; 4724 res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0; 4725 res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0; 4726 } 4727 return res; 4728 } 4729 function computeInnerRect(el, goWithinPadding, doFromWindowViewport) { 4730 if (goWithinPadding === void 0) { goWithinPadding = false; } 4731 var outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el); 4732 var edges = computeEdges(el, goWithinPadding); 4733 var res = { 4734 left: outerRect.left + edges.borderLeft + edges.scrollbarLeft, 4735 right: outerRect.right - edges.borderRight - edges.scrollbarRight, 4736 top: outerRect.top + edges.borderTop, 4737 bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom, 4738 }; 4739 if (goWithinPadding) { 4740 res.left += edges.paddingLeft; 4741 res.right -= edges.paddingRight; 4742 res.top += edges.paddingTop; 4743 res.bottom -= edges.paddingBottom; 4744 } 4745 return res; 4746 } 4747 function computeRect(el) { 4748 var rect = el.getBoundingClientRect(); 4749 return { 4750 left: rect.left + window.pageXOffset, 4751 top: rect.top + window.pageYOffset, 4752 right: rect.right + window.pageXOffset, 4753 bottom: rect.bottom + window.pageYOffset, 4754 }; 4755 } 4756 function computeClippedClientRect(el) { 4757 var clippingParents = getClippingParents(el); 4758 var rect = el.getBoundingClientRect(); 4759 for (var _i = 0, clippingParents_1 = clippingParents; _i < clippingParents_1.length; _i++) { 4760 var clippingParent = clippingParents_1[_i]; 4761 var intersection = intersectRects(rect, clippingParent.getBoundingClientRect()); 4762 if (intersection) { 4763 rect = intersection; 4764 } 4765 else { 4766 return null; 4767 } 4768 } 4769 return rect; 4770 } 4771 function computeHeightAndMargins(el) { 4772 return el.getBoundingClientRect().height + computeVMargins(el); 4773 } 4774 function computeVMargins(el) { 4775 var computed = window.getComputedStyle(el); 4776 return parseInt(computed.marginTop, 10) + 4777 parseInt(computed.marginBottom, 10); 4778 } 4779 // does not return window 4780 function getClippingParents(el) { 4781 var parents = []; 4782 while (el instanceof HTMLElement) { // will stop when gets to document or null 4783 var computedStyle = window.getComputedStyle(el); 4784 if (computedStyle.position === 'fixed') { 4785 break; 4786 } 4787 if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) { 4788 parents.push(el); 4789 } 4790 el = el.parentNode; 4791 } 4792 return parents; 4793 } 4794 4795 // given a function that resolves a result asynchronously. 4796 // the function can either call passed-in success and failure callbacks, 4797 // or it can return a promise. 4798 // if you need to pass additional params to func, bind them first. 4799 function unpromisify(func, success, failure) { 4800 // guard against success/failure callbacks being called more than once 4801 // and guard against a promise AND callback being used together. 4802 var isResolved = false; 4803 var wrappedSuccess = function () { 4804 if (!isResolved) { 4805 isResolved = true; 4806 success.apply(this, arguments); // eslint-disable-line prefer-rest-params 4807 } 4808 }; 4809 var wrappedFailure = function () { 4810 if (!isResolved) { 4811 isResolved = true; 4812 if (failure) { 4813 failure.apply(this, arguments); // eslint-disable-line prefer-rest-params 4814 } 4815 } 4816 }; 4817 var res = func(wrappedSuccess, wrappedFailure); 4818 if (res && typeof res.then === 'function') { 4819 res.then(wrappedSuccess, wrappedFailure); 4820 } 4821 } 4822 4823 var Emitter = /** @class */ (function () { 4824 function Emitter() { 4825 this.handlers = {}; 4826 this.thisContext = null; 4827 } 4828 Emitter.prototype.setThisContext = function (thisContext) { 4829 this.thisContext = thisContext; 4830 }; 4831 Emitter.prototype.setOptions = function (options) { 4832 this.options = options; 4833 }; 4834 Emitter.prototype.on = function (type, handler) { 4835 addToHash(this.handlers, type, handler); 4836 }; 4837 Emitter.prototype.off = function (type, handler) { 4838 removeFromHash(this.handlers, type, handler); 4839 }; 4840 Emitter.prototype.trigger = function (type) { 4841 var args = []; 4842 for (var _i = 1; _i < arguments.length; _i++) { 4843 args[_i - 1] = arguments[_i]; 4844 } 4845 var attachedHandlers = this.handlers[type] || []; 4846 var optionHandler = this.options && this.options[type]; 4847 var handlers = [].concat(optionHandler || [], attachedHandlers); 4848 for (var _a = 0, handlers_1 = handlers; _a < handlers_1.length; _a++) { 4849 var handler = handlers_1[_a];
4850 handler.apply(this.thisContext, args); 4851 } 4852 }; 4853 Emitter.prototype.hasHandlers = function (type) { 4854 return Boolean((this.handlers[type] && this.handlers[type].length) || 4855 (this.options && this.options[type])); 4856 }; 4857 return Emitter; 4858 }()); 4859 function addToHash(hash, type, handler) { 4860 (hash[type] || (hash[type] = [])) 4861 .push(handler); 4862 } 4863 function removeFromHash(hash, type, handler) { 4864 if (handler) { 4865 if (hash[type]) { 4866 hash[type] = hash[type].filter(function (func) { return func !== handler; }); 4867 } 4868 } 4869 else { 4870 delete hash[type]; // remove all handler funcs for this type 4871 } 4872 } 4873 4874 /* 4875 Records offset information for a set of elements, relative to an origin element. 4876 Can record the left/right OR the top/bottom OR both. 4877 Provides methods for querying the cache by position. 4878 */ 4879 var PositionCache = /** @class */ (function () { 4880 function PositionCache(originEl, els, isHorizontal, isVertical) { 4881 this.els = els; 4882 var originClientRect = this.originClientRect = originEl.getBoundingClientRect(); // relative to viewport top-left 4883 if (isHorizontal) { 4884 this.buildElHorizontals(originClientRect.left); 4885 } 4886 if (isVertical) { 4887 this.buildElVerticals(originClientRect.top); 4888 } 4889 } 4890 // Populates the left/right internal coordinate arrays 4891 PositionCache.prototype.buildElHorizontals = function (originClientLeft) { 4892 var lefts = []; 4893 var rights = []; 4894 for (var _i = 0, _a = this.els; _i < _a.length; _i++) { 4895 var el = _a[_i]; 4896 var rect = el.getBoundingClientRect(); 4897 lefts.push(rect.left - originClientLeft); 4898 rights.push(rect.right - originClientLeft); 4899 } 4900 this.lefts = lefts; 4901 this.rights = rights; 4902 }; 4903 // Populates the top/bottom internal coordinate arrays 4904 PositionCache.prototype.buildElVerticals = function (originClientTop) { 4905 var tops = []; 4906 var bottoms = []; 4907 for (var _i = 0, _a = this.els; _i < _a.length; _i++) { 4908 var el = _a[_i]; 4909 var rect = el.getBoundingClientRect(); 4910 tops.push(rect.top - originClientTop); 4911 bottoms.push(rect.bottom - originClientTop); 4912 } 4913 this.tops = tops; 4914 this.bottoms = bottoms; 4915 }; 4916 // Given a left offset (from document left), returns the index of the el that it horizontally intersects. 4917 // If no intersection is made, returns undefined. 4918 PositionCache.prototype.leftToIndex = function (leftPosition) { 4919 var _a = this, lefts = _a.lefts, rights = _a.rights; 4920 var len = lefts.length; 4921 var i; 4922 for (i = 0; i < len; i += 1) { 4923 if (leftPosition >= lefts[i] && leftPosition < rights[i]) { 4924 return i; 4925 } 4926 } 4927 return undefined; // TODO: better 4928 }; 4929 // Given a top offset (from document top), returns the index of the el that it vertically intersects. 4930 // If no intersection is made, returns undefined. 4931 PositionCache.prototype.topToIndex = function (topPosition) { 4932 var _a = this, tops = _a.tops, bottoms = _a.bottoms; 4933 var len = tops.length; 4934 var i; 4935 for (i = 0; i < len; i += 1) { 4936 if (topPosition >= tops[i] && topPosition < bottoms[i]) { 4937 return i; 4938 } 4939 } 4940 return undefined; // TODO: better 4941 }; 4942 // Gets the width of the element at the given index 4943 PositionCache.prototype.getWidth = function (leftIndex) { 4944 return this.rights[leftIndex] - this.lefts[leftIndex]; 4945 }; 4946 // Gets the height of the element at the given index 4947 PositionCache.prototype.getHeight = function (topIndex) { 4948 return this.bottoms[topIndex] - this.tops[topIndex]; 4949 }; 4950 return PositionCache; 4951 }()); 4952
4953 /* eslint max-classes-per-file: "off" */ 4954 /* 4955 An object for getting/setting scroll-related information for an element. 4956 Internally, this is done very differently for window versus DOM element, 4957 so this object serves as a common interface. 4958 */ 4959 var ScrollController = /** @class */ (function () { 4960 function ScrollController() { 4961 } 4962 ScrollController.prototype.getMaxScrollTop = function () { 4963 return this.getScrollHeight() - this.getClientHeight(); 4964 }; 4965 ScrollController.prototype.getMaxScrollLeft = function () { 4966 return this.getScrollWidth() - this.getClientWidth(); 4967 }; 4968 ScrollController.prototype.canScrollVertically = function () { 4969 return this.getMaxScrollTop() > 0; 4970 }; 4971 ScrollController.prototype.canScrollHorizontally = function () { 4972 return this.getMaxScrollLeft() > 0; 4973 }; 4974 ScrollController.prototype.canScrollUp = function () { 4975 return this.getScrollTop() > 0; 4976 }; 4977 ScrollController.prototype.canScrollDown = function () { 4978 return this.getScrollTop() < this.getMaxScrollTop(); 4979 }; 4980 ScrollController.prototype.canScrollLeft = function () { 4981 return this.getScrollLeft() > 0; 4982 }; 4983 ScrollController.prototype.canScrollRight = function () { 4984 return this.getScrollLeft() < this.getMaxScrollLeft(); 4985 }; 4986 return ScrollController; 4987 }()); 4988 var ElementScrollController = /** @class */ (function (_super) { 4989 __extends(ElementScrollController, _super); 4990 function ElementScrollController(el) { 4991 var _this = _super.call(this) || this; 4992 _this.el = el; 4993 return _this; 4994 } 4995 ElementScrollController.prototype.getScrollTop = function () { 4996 return this.el.scrollTop; 4997 }; 4998 ElementScrollController.prototype.getScrollLeft = function () { 4999 return this.el.scrollLeft; 5000 }; 5001 ElementScrollController.prototype.setScrollTop = function (top) { 5002 this.el.scrollTop = top; 5003 }; 5004 ElementScrollController.prototype.setScrollLeft = function (left) { 5005 this.el.scrollLeft = left; 5006 }; 5007 ElementScrollController.prototype.getScrollWidth = function () { 5008 return this.el.scrollWidth; 5009 }; 5010 ElementScrollController.prototype.getScrollHeight = function () { 5011 return this.el.scrollHeight; 5012 }; 5013 ElementScrollController.prototype.getClientHeight = function () { 5014 return this.el.clientHeight; 5015 }; 5016 ElementScrollController.prototype.getClientWidth = function () { 5017 return this.el.clientWidth; 5018 }; 5019 return ElementScrollController; 5020 }(ScrollController)); 5021 var WindowScrollController = /** @class */ (function (_super) { 5022 __extends(WindowScrollController, _super); 5023 function WindowScrollController() { 5024 return _super !== null && _super.apply(this, arguments) || this; 5025 } 5026 WindowScrollController.prototype.getScrollTop = function () { 5027 return window.pageYOffset; 5028 }; 5029 WindowScrollController.prototype.getScrollLeft = function () { 5030 return window.pageXOffset; 5031 }; 5032 WindowScrollController.prototype.setScrollTop = function (n) { 5033 window.scroll(window.pageXOffset, n); 5034 }; 5035 WindowScrollController.prototype.setScrollLeft = function (n) { 5036 window.scroll(n, window.pageYOffset); 5037 }; 5038 WindowScrollController.prototype.getScrollWidth = function () { 5039 return document.documentElement.scrollWidth; 5040 }; 5041 WindowScrollController.prototype.getScrollHeight = function () { 5042 return document.documentElement.scrollHeight; 5043 }; 5044 WindowScrollController.prototype.getClientHeight = function () { 5045 return document.documentElement.clientHeight; 5046 }; 5047 WindowScrollController.prototype.getClientWidth = function () { 5048 return document.documentElement.clientWidth; 5049 }; 5050 return WindowScrollController; 5051 }(ScrollController)); 5052 5053 var Theme = /** @class */ (function () { 5054 function Theme(calendarOptions) { 5055 if (this.iconOverrideOption) { 5056 this.setIconOverride(calendarOptions[this.iconOverrideOption]); 5057 } 5058 } 5059 Theme.prototype.setIconOverride = function (iconOverrideHash) { 5060 var iconClassesCopy; 5061 var buttonName; 5062 if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object 5063 iconClassesCopy = __assign({}, this.iconClasses); 5064 for (buttonName in iconOverrideHash) { 5065 iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]); 5066 } 5067 this.iconClasses = iconClassesCopy; 5068 } 5069 else if (iconOverrideHash === false) { 5070 this.iconClasses = {}; 5071 } 5072 }; 5073 Theme.prototype.applyIconOverridePrefix = function (className) { 5074 var prefix = this.iconOverridePrefix; 5075 if (prefix && className.indexOf(prefix) !== 0) { // if not already present 5076 className = prefix + className; 5077 } 5078 return className; 5079 }; 5080 Theme.prototype.getClass = function (key) { 5081 return this.classes[key] || ''; 5082 }; 5083 Theme.prototype.getIconClass = function (buttonName, isRtl) { 5084 var className; 5085 if (isRtl && this.rtlIconClasses) { 5086 className = this.rtlIconClasses[buttonName] || this.iconClasses[buttonName]; 5087 } 5088 else { 5089 className = this.iconClasses[buttonName]; 5090 } 5091 if (className) { 5092 return this.baseIconClass + " " + className; 5093 } 5094 return ''; 5095 }; 5096 Theme.prototype.getCustomButtonIconClass = function (customButtonProps) { 5097 var className; 5098 if (this.iconOverrideCustomButtonOption) { 5099 className = customButtonProps[this.iconOverrideCustomButtonOption]; 5100 if (className) { 5101 return this.baseIconClass + " " + this.applyIconOverridePrefix(className); 5102 } 5103 } 5104 return ''; 5105 }; 5106 return Theme; 5107 }()); 5108 Theme.prototype.classes = {}; 5109 Theme.prototype.iconClasses = {}; 5110 Theme.prototype.baseIconClass = ''; 5111 Theme.prototype.iconOverridePrefix = ''; 5112 5113 /// <reference types="@fullcalendar/core-preact" /> 5114 if (typeof FullCalendarVDom === 'undefined') { 5115 throw new Error('Please import the top-level fullcalendar lib before attempting to import a plugin.'); 5116 } 5117 var Component = FullCalendarVDom.Component; 5118 var createElement = FullCalendarVDom.createElement; 5119 var render = FullCalendarVDom.render; 5120 var createRef = FullCalendarVDom.createRef; 5121 var Fragment = FullCalendarVDom.Fragment; 5122 var createContext = FullCalendarVDom.createContext; 5123 var createPortal = FullCalendarVDom.createPortal; 5124 var flushSync = FullCalendarVDom.flushSync; 5125 var unmountComponentAtNode = FullCalendarVDom.unmountComponentAtNode; 5126 /* eslint-enable */ 5127 5128 var ScrollResponder = /** @class */ (function () { 5129 function ScrollResponder(execFunc, emitter, scrollTime, scrollTimeReset) { 5130 var _this = this; 5131 this.execFunc = execFunc; 5132 this.emitter = emitter; 5133 this.scrollTime = scrollTime; 5134 this.scrollTimeReset = scrollTimeReset; 5135 this.handleScrollRequest = function (request) { 5136 _this.queuedRequest = __assign({}, _this.queuedRequest || {}, request); 5137 _this.drain(); 5138 }; 5139 emitter.on('_scrollRequest', this.handleScrollRequest); 5140 this.fireInitialScroll(); 5141 } 5142 ScrollResponder.prototype.detach = function () { 5143 this.emitter.off('_scrollRequest', this.handleScrollRequest); 5144 }; 5145 ScrollResponder.prototype.update = function (isDatesNew) { 5146 if (isDatesNew && this.scrollTimeReset) { 5147 this.fireInitialScroll(); // will drain 5148 } 5149 else { 5150 this.drain(); 5151 } 5152 }; 5153 ScrollResponder.prototype.fireInitialScroll = function () { 5154 this.handleScrollRequest({ 5155 time: this.scrollTime, 5156 }); 5157 };
5158 ScrollResponder.prototype.drain = function () { 5159 if (this.queuedRequest && this.execFunc(this.queuedRequest)) { 5160 this.queuedRequest = null; 5161 } 5162 }; 5163 return ScrollResponder; 5164 }()); 5165 5166 var ViewContextType = createContext({}); // for Components 5167 function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) { 5168 return { 5169 dateEnv: dateEnv, 5170 options: viewOptions, 5171 pluginHooks: pluginHooks, 5172 emitter: emitter, 5173 dispatch: dispatch, 5174 getCurrentData: getCurrentData, 5175 calendarApi: calendarApi, 5176 viewSpec: viewSpec, 5177 viewApi: viewApi, 5178 dateProfileGenerator: dateProfileGenerator, 5179 theme: theme, 5180 isRtl: viewOptions.direction === 'rtl', 5181 addResizeHandler: function (handler) { 5182 emitter.on('_resize', handler); 5183 }, 5184 removeResizeHandler: function (handler) { 5185 emitter.off('_resize', handler); 5186 }, 5187 createScrollResponder: function (execFunc) { 5188 return new ScrollResponder(execFunc, emitter, createDuration(viewOptions.scrollTime), viewOptions.scrollTimeReset); 5189 }, 5190 registerInteractiveComponent: registerInteractiveComponent, 5191 unregisterInteractiveComponent: unregisterInteractiveComponent, 5192 }; 5193 } 5194 5195 /* eslint max-classes-per-file: off */ 5196 var PureComponent = /** @class */ (function (_super) { 5197 __extends(PureComponent, _super); 5198 function PureComponent() { 5199 return _super !== null && _super.apply(this, arguments) || this; 5200 } 5201 PureComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) { 5202 if (this.debug) { 5203 // eslint-disable-next-line no-console 5204 console.log(getUnequalProps(nextProps, this.props), getUnequalProps(nextState, this.state)); 5205 } 5206 return !compareObjs(this.props, nextProps, this.propEquality) || 5207 !compareObjs(this.state, nextState, this.stateEquality); 5208 }; 5209 PureComponent.addPropsEquality = addPropsEquality; 5210 PureComponent.addStateEquality = addStateEquality; 5211 PureComponent.contextType = ViewContextType; 5212 return PureComponent; 5213 }(Component)); 5214 PureComponent.prototype.propEquality = {}; 5215 PureComponent.prototype.stateEquality = {}; 5216 var BaseComponent = /** @class */ (function (_super) { 5217 __extends(BaseComponent, _super); 5218 function BaseComponent() { 5219 return _super !== null && _super.apply(this, arguments) || this; 5220 } 5221 BaseComponent.contextType = ViewContextType; 5222 return BaseComponent; 5223 }(PureComponent)); 5224 function addPropsEquality(propEquality) { 5225 var hash = Object.create(this.prototype.propEquality); 5226 __assign(hash, propEquality); 5227 this.prototype.propEquality = hash; 5228 } 5229 function addStateEquality(stateEquality) { 5230 var hash = Object.create(this.prototype.stateEquality); 5231 __assign(hash, stateEquality); 5232 this.prototype.stateEquality = hash; 5233 } 5234 // use other one 5235 function setRef(ref, current) { 5236 if (typeof ref === 'function') { 5237 ref(current); 5238 } 5239 else if (ref) { 5240 // see https://github.com/facebook/react/issues/13029 5241 ref.current = current; 5242 } 5243 } 5244 5245 /* 5246 an INTERACTABLE date component 5247 5248 PURPOSES: 5249 - hook up to fg, fill, and mirror renderers 5250 - interface for dragging and hits 5251 */ 5252 var DateComponent = /** @class */ (function (_super) { 5253 __extends(DateComponent, _super); 5254 function DateComponent() { 5255 var _this = _super !== null && _super.apply(this, arguments) || this; 5256 _this.uid = guid(); 5257 return _this; 5258 } 5259 // Hit System 5260 // ----------------------------------------------------------------------------------------------------------------- 5261 DateComponent.prototype.prepareHits = function () { 5262 }; 5263 DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) { 5264 return null; // this should be abstract 5265 }; 5266 // Pointer Interaction Utils 5267 // ----------------------------------------------------------------------------------------------------------------- 5268 DateComponent.prototype.isValidSegDownEl = function (el) { 5269 return !this.props.eventDrag && // HACK 5270 !this.props.eventResize && // HACK 5271 !elementClosest(el, '.fc-event-mirror'); 5272 }; 5273 DateComponent.prototype.isValidDateDownEl = function (el) { 5274 return !elementClosest(el, '.fc-event:not(.fc-bg-event)') && 5275 !elementClosest(el, '.fc-more-link') && // a "more.." link 5276 !elementClosest(el, 'a[data-navlink]') && // a clickable nav link 5277 !elementClosest(el, '.fc-popover'); // hack 5278 }; 5279 return DateComponent; 5280 }(BaseComponent)); 5281 5282 // TODO: easier way to add new hooks? need to update a million things 5283 function createPlugin(input) { 5284 return { 5285 id: guid(), 5286 deps: input.deps || [], 5287 reducers: input.reducers || [], 5288 isLoadingFuncs: input.isLoadingFuncs || [], 5289 contextInit: [].concat(input.contextInit || []), 5290 eventRefiners: input.eventRefiners || {}, 5291 eventDefMemberAdders: input.eventDefMemberAdders || [], 5292 eventSourceRefiners: input.eventSourceRefiners || {}, 5293 isDraggableTransformers: input.isDraggableTransformers || [], 5294 eventDragMutationMassagers: input.eventDragMutationMassagers || [], 5295 eventDefMutationAppliers: input.eventDefMutationAppliers || [], 5296 dateSelectionTransformers: input.dateSelectionTransformers || [], 5297 datePointTransforms: input.datePointTransforms || [], 5298 dateSpanTransforms: input.dateSpanTransforms || [], 5299 views: input.views || {}, 5300 viewPropsTransformers: input.viewPropsTransformers || [], 5301 isPropsValid: input.isPropsValid || null, 5302 externalDefTransforms: input.externalDefTransforms || [], 5303 viewContainerAppends: input.viewContainerAppends || [], 5304 eventDropTransformers: input.eventDropTransformers || [], 5305 componentInteractions: input.componentInteractions || [], 5306 calendarInteractions: input.calendarInteractions || [],
5307 themeClasses: input.themeClasses || {}, 5308 eventSourceDefs: input.eventSourceDefs || [], 5309 cmdFormatter: input.cmdFormatter, 5310 recurringTypes: input.recurringTypes || [], 5311 namedTimeZonedImpl: input.namedTimeZonedImpl, 5312 initialView: input.initialView || '', 5313 elementDraggingImpl: input.elementDraggingImpl, 5314 optionChangeHandlers: input.optionChangeHandlers || {}, 5315 scrollGridImpl: input.scrollGridImpl || null, 5316 contentTypeHandlers: input.contentTypeHandlers || {}, 5317 listenerRefiners: input.listenerRefiners || {}, 5318 optionRefiners: input.optionRefiners || {}, 5319 propSetHandlers: input.propSetHandlers || {}, 5320 }; 5321 } 5322 function buildPluginHooks(pluginDefs, globalDefs) { 5323 var isAdded = {}; 5324 var hooks = { 5325 reducers: [], 5326 isLoadingFuncs: [], 5327 contextInit: [], 5328 eventRefiners: {}, 5329 eventDefMemberAdders: [], 5330 eventSourceRefiners: {}, 5331 isDraggableTransformers: [], 5332 eventDragMutationMassagers: [], 5333 eventDefMutationAppliers: [], 5334 dateSelectionTransformers: [], 5335 datePointTransforms: [], 5336 dateSpanTransforms: [], 5337 views: {}, 5338 viewPropsTransformers: [], 5339 isPropsValid: null, 5340 externalDefTransforms: [], 5341 viewContainerAppends: [], 5342 eventDropTransformers: [], 5343 componentInteractions: [], 5344 calendarInteractions: [], 5345 themeClasses: {}, 5346 eventSourceDefs: [], 5347 cmdFormatter: null, 5348 recurringTypes: [], 5349 namedTimeZonedImpl: null, 5350 initialView: '', 5351 elementDraggingImpl: null, 5352 optionChangeHandlers: {}, 5353 scrollGridImpl: null, 5354 contentTypeHandlers: {}, 5355 listenerRefiners: {}, 5356 optionRefiners: {}, 5357 propSetHandlers: {}, 5358 }; 5359 function addDefs(defs) { 5360 for (var _i = 0, defs_1 = defs; _i < defs_1.length; _i++) { 5361 var def = defs_1[_i]; 5362 if (!isAdded[def.id]) { 5363 isAdded[def.id] = true; 5364 addDefs(def.deps); 5365 hooks = combineHooks(hooks, def); 5366 } 5367 } 5368 } 5369 if (pluginDefs) { 5370 addDefs(pluginDefs); 5371 } 5372 addDefs(globalDefs); 5373 return hooks; 5374 } 5375 function buildBuildPluginHooks() { 5376 var currentOverrideDefs = []; 5377 var currentGlobalDefs = []; 5378 var currentHooks; 5379 return function (overrideDefs, globalDefs) { 5380 if (!currentHooks || !isArraysEqual(overrideDefs, currentOverrideDefs) || !isArraysEqual(globalDefs, currentGlobalDefs)) { 5381 currentHooks = buildPluginHooks(overrideDefs, globalDefs); 5382 } 5383 currentOverrideDefs = overrideDefs; 5384 currentGlobalDefs = globalDefs; 5385 return currentHooks; 5386 }; 5387 } 5388 function combineHooks(hooks0, hooks1) { 5389 return { 5390 reducers: hooks0.reducers.concat(hooks1.reducers), 5391 isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs), 5392 contextInit: hooks0.contextInit.concat(hooks1.contextInit), 5393 eventRefiners: __assign(__assign({}, hooks0.eventRefiners), hooks1.eventRefiners), 5394 eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders), 5395 eventSourceRefiners: __assign(__assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners), 5396 isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers), 5397 eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers), 5398 eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers), 5399 dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers), 5400 datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms), 5401 dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms), 5402 views: __assign(__assign({}, hooks0.views), hooks1.views), 5403 viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers), 5404 isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid, 5405 externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms), 5406 viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends), 5407 eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers), 5408 calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions), 5409 componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
5410 themeClasses: __assign(__assign({}, hooks0.themeClasses), hooks1.themeClasses), 5411 eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs), 5412 cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter, 5413 recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes), 5414 namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl, 5415 initialView: hooks0.initialView || hooks1.initialView, 5416 elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl, 5417 optionChangeHandlers: __assign(__assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers), 5418 scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl, 5419 contentTypeHandlers: __assign(__assign({}, hooks0.contentTypeHandlers), hooks1.contentTypeHandlers), 5420 listenerRefiners: __assign(__assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners), 5421 optionRefiners: __assign(__assign({}, hooks0.optionRefiners), hooks1.optionRefiners), 5422 propSetHandlers: __assign(__assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers), 5423 }; 5424 } 5425 5426 var StandardTheme = /** @class */ (function (_super) { 5427 __extends(StandardTheme, _super); 5428 function StandardTheme() { 5429 return _super !== null && _super.apply(this, arguments) || this; 5430 } 5431 return StandardTheme; 5432 }(Theme)); 5433 StandardTheme.prototype.classes = { 5434 root: 'fc-theme-standard', 5435 tableCellShaded: 'fc-cell-shaded', 5436 buttonGroup: 'fc-button-group', 5437 button: 'fc-button fc-button-primary', 5438 buttonActive: 'fc-button-active', 5439 }; 5440 StandardTheme.prototype.baseIconClass = 'fc-icon'; 5441 StandardTheme.prototype.iconClasses = { 5442 close: 'fc-icon-x', 5443 prev: 'fc-icon-chevron-left', 5444 next: 'fc-icon-chevron-right', 5445 prevYear: 'fc-icon-chevrons-left', 5446 nextYear: 'fc-icon-chevrons-right', 5447 }; 5448 StandardTheme.prototype.rtlIconClasses = { 5449 prev: 'fc-icon-chevron-right', 5450 next: 'fc-icon-chevron-left', 5451 prevYear: 'fc-icon-chevrons-right', 5452 nextYear: 'fc-icon-chevrons-left', 5453 }; 5454 StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly 5455 StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon'; 5456 StandardTheme.prototype.iconOverridePrefix = 'fc-icon-'; 5457 5458 function compileViewDefs(defaultConfigs, overrideConfigs) { 5459 var hash = {}; 5460 var viewType; 5461 for (viewType in defaultConfigs) { 5462 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5463 } 5464 for (viewType in overrideConfigs) { 5465 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5466 } 5467 return hash; 5468 } 5469 function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 5470 if (hash[viewType]) { 5471 return hash[viewType]; 5472 } 5473 var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5474 if (viewDef) { 5475 hash[viewType] = viewDef; 5476 } 5477 return viewDef; 5478 } 5479 function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 5480 var defaultConfig = defaultConfigs[viewType]; 5481 var overrideConfig = overrideConfigs[viewType]; 5482 var queryProp = function (name) { return ((defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] : 5483 ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null)); }; 5484 var theComponent = queryProp('component'); 5485 var superType = queryProp('superType'); 5486 var superDef = null; 5487 if (superType) { 5488 if (superType === viewType) { 5489 throw new Error('Can\'t have a custom view type that references itself'); 5490 } 5491 superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs); 5492 } 5493 if (!theComponent && superDef) { 5494 theComponent = superDef.component; 5495 } 5496 if (!theComponent) { 5497 return null; // don't throw a warning, might be settings for a single-unit view 5498 } 5499 return { 5500 type: viewType, 5501 component: theComponent, 5502 defaults: __assign(__assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})), 5503 overrides: __assign(__assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {})), 5504 }; 5505 } 5506
5507 /* eslint max-classes-per-file: off */ 5508 // NOTE: in JSX, you should always use this class with <HookProps> arg. otherwise, will default to any??? 5509 var RenderHook = /** @class */ (function (_super) { 5510 __extends(RenderHook, _super); 5511 function RenderHook() { 5512 var _this = _super !== null && _super.apply(this, arguments) || this; 5513 _this.rootElRef = createRef(); 5514 _this.handleRootEl = function (el) { 5515 setRef(_this.rootElRef, el); 5516 if (_this.props.elRef) { 5517 setRef(_this.props.elRef, el); 5518 } 5519 }; 5520 return _this; 5521 } 5522 RenderHook.prototype.render = function () { 5523 var _this = this; 5524 var props = this.props; 5525 var hookProps = props.hookProps; 5526 return (createElement(MountHook, { hookProps: hookProps, didMount: props.didMount, willUnmount: props.willUnmount, elRef: this.handleRootEl }, function (rootElRef) { return (createElement(ContentHook, { hookProps: hookProps, content: props.content, defaultContent: props.defaultContent, backupElRef: _this.rootElRef }, function (innerElRef, innerContent) { return props.children(rootElRef, normalizeClassNames(props.classNames, hookProps), innerElRef, innerContent); })); })); 5527 }; 5528 return RenderHook; 5529 }(BaseComponent)); 5530 // TODO: rename to be about function, not default. use in above type 5531 // for forcing rerender of components that use the ContentHook 5532 var CustomContentRenderContext = createContext(0); 5533 function ContentHook(props) { 5534 return (createElement(CustomContentRenderContext.Consumer, null, function (renderId) { return (createElement(ContentHookInner, __assign({ renderId: renderId }, props))); })); 5535 } 5536 var ContentHookInner = /** @class */ (function (_super) { 5537 __extends(ContentHookInner, _super); 5538 function ContentHookInner() { 5539 var _this = _super !== null && _super.apply(this, arguments) || this; 5540 _this.innerElRef = createRef(); 5541 return _this; 5542 } 5543 ContentHookInner.prototype.render = function () { 5544 return this.props.children(this.innerElRef, this.renderInnerContent()); 5545 }; 5546 ContentHookInner.prototype.componentDidMount = function () { 5547 this.updateCustomContent(); 5548 }; 5549 ContentHookInner.prototype.componentDidUpdate = function () { 5550 this.updateCustomContent(); 5551 }; 5552 ContentHookInner.prototype.componentWillUnmount = function () { 5553 if (this.customContentInfo && this.customContentInfo.destroy) { 5554 this.customContentInfo.destroy(); 5555 } 5556 }; 5557 ContentHookInner.prototype.renderInnerContent = function () { 5558 var customContentInfo = this.customContentInfo; // only populated if using non-[p]react node(s) 5559 var innerContent = this.getInnerContent(); 5560 var meta = this.getContentMeta(innerContent); 5561 // initial run, or content-type changing? (from vue -> react for example) 5562 if (!customContentInfo || customContentInfo.contentKey !== meta.contentKey) { 5563 // clearing old value 5564 if (customContentInfo) { 5565 if (customContentInfo.destroy) { 5566 customContentInfo.destroy(); 5567 } 5568 customContentInfo = this.customContentInfo = null; 5569 } 5570 // assigning new value 5571 if (meta.contentKey) { 5572 customContentInfo = this.customContentInfo = __assign({ contentKey: meta.contentKey, contentVal: innerContent[meta.contentKey] }, meta.buildLifecycleFuncs()); 5573 } 5574 // updating 5575 } 5576 else if (customContentInfo) { 5577 customContentInfo.contentVal = innerContent[meta.contentKey]; 5578 } 5579 return customContentInfo 5580 ? [] // signal that something was specified 5581 : innerContent; // assume a [p]react vdom node. use it 5582 }; 5583 ContentHookInner.prototype.getInnerContent = function () { 5584 var props = this.props; 5585 var innerContent = normalizeContent(props.content, props.hookProps); 5586 if (innerContent === undefined) { // use the default 5587 innerContent = normalizeContent(props.defaultContent, props.hookProps); 5588 } 5589 return innerContent == null ? null : innerContent; // convert undefined to null (better for React) 5590 }; 5591 ContentHookInner.prototype.getContentMeta = function (innerContent) { 5592 var contentTypeHandlers = this.context.pluginHooks.contentTypeHandlers; 5593 var contentKey = ''; 5594 var buildLifecycleFuncs = null; 5595 if (innerContent) { // allowed to be null, for convenience to caller 5596 for (var searchKey in contentTypeHandlers) { 5597 if (innerContent[searchKey] !== undefined) { 5598 contentKey = searchKey; 5599 buildLifecycleFuncs = contentTypeHandlers[searchKey]; 5600 break; 5601 } 5602 } 5603 } 5604 return { contentKey: contentKey, buildLifecycleFuncs: buildLifecycleFuncs }; 5605 }; 5606 ContentHookInner.prototype.updateCustomContent = function () { 5607 if (this.customContentInfo) { // for non-[p]react 5608 this.customContentInfo.render(this.innerElRef.current || this.props.backupElRef.current, // the element to render into 5609 this.customContentInfo.contentVal); 5610 } 5611 }; 5612 return ContentHookInner; 5613 }(BaseComponent)); 5614 var MountHook = /** @class */ (function (_super) { 5615 __extends(MountHook, _super); 5616 function MountHook() { 5617 var _this = _super !== null && _super.apply(this, arguments) || this; 5618 _this.handleRootEl = function (rootEl) { 5619 _this.rootEl = rootEl; 5620 if (_this.props.elRef) { 5621 setRef(_this.props.elRef, rootEl); 5622 } 5623 }; 5624 return _this; 5625 } 5626 MountHook.prototype.render = function () { 5627 return this.props.children(this.handleRootEl); 5628 }; 5629 MountHook.prototype.componentDidMount = function () { 5630 var callback = this.props.didMount; 5631 if (callback) { 5632 callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl })); 5633 } 5634 }; 5635 MountHook.prototype.componentWillUnmount = function () { 5636 var callback = this.props.willUnmount; 5637 if (callback) { 5638 callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl })); 5639 } 5640 }; 5641 return MountHook; 5642 }(BaseComponent)); 5643 function buildClassNameNormalizer() { 5644 var currentGenerator; 5645 var currentHookProps; 5646 var currentClassNames = []; 5647 return function (generator, hookProps) { 5648 if (!currentHookProps || !isPropsEqual(currentHookProps, hookProps) || generator !== currentGenerator) { 5649 currentGenerator = generator; 5650 currentHookProps = hookProps; 5651 currentClassNames = normalizeClassNames(generator, hookProps); 5652 } 5653 return currentClassNames; 5654 }; 5655 } 5656 function normalizeClassNames(classNames, hookProps) { 5657 if (typeof classNames === 'function') { 5658 classNames = classNames(hookProps); 5659 } 5660 return parseClassNames(classNames); 5661 } 5662 function normalizeContent(input, hookProps) { 5663 if (typeof input === 'function') { 5664 return input(hookProps, createElement); // give the function the vdom-creation func 5665 } 5666 return input; 5667 } 5668 5669 var ViewRoot = /** @class */ (function (_super) { 5670 __extends(ViewRoot, _super); 5671 function ViewRoot() { 5672 var _this = _super !== null && _super.apply(this, arguments) || this; 5673 _this.normalizeClassNames = buildClassNameNormalizer(); 5674 return _this; 5675 } 5676 ViewRoot.prototype.render = function () { 5677 var _a = this, props = _a.props, context = _a.context; 5678 var options = context.options; 5679 var hookProps = { view: context.viewApi }; 5680 var customClassNames = this.normalizeClassNames(options.viewClassNames, hookProps); 5681 return (createElement(MountHook, { hookProps: hookProps, didMount: options.viewDidMount, willUnmount: options.viewWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, ["fc-" + props.viewSpec.type + "-view", 'fc-view'].concat(customClassNames)); })); 5682 }; 5683 return ViewRoot; 5684 }(BaseComponent)); 5685 5686 function parseViewConfigs(inputs) { 5687 return mapHash(inputs, parseViewConfig); 5688 } 5689 function parseViewConfig(input) { 5690 var rawOptions = typeof input === 'function' ? 5691 { component: input } : 5692 input; 5693 var component = rawOptions.component; 5694 if (rawOptions.content) { 5695 component = createViewHookComponent(rawOptions); 5696 // TODO: remove content/classNames/didMount/etc from options? 5697 } 5698 return { 5699 superType: rawOptions.type, 5700 component: component, 5701 rawOptions: rawOptions, 5702 }; 5703 } 5704 function createViewHookComponent(options) { 5705 return function (viewProps) { return (createElement(ViewContextType.Consumer, null, function (context) { return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (viewElRef, viewClassNames) { 5706 var hookProps = __assign(__assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold }); 5707 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.classNames, content: options.content, didMount: options.didMount, willUnmount: options.willUnmount, elRef: viewElRef }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("div", { className: viewClassNames.c
5707oncat(customClassNames).join(' '), ref: rootElRef }, innerContent)); })); 5708 })); })); }; 5709 } 5710 5711 function buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) { 5712 var defaultConfigs = parseViewConfigs(defaultInputs); 5713 var overrideConfigs = parseViewConfigs(optionOverrides.views); 5714 var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs); 5715 return mapHash(viewDefs, function (viewDef) { return buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults); }); 5716 } 5717 function buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) { 5718 var durationInput = viewDef.overrides.duration || 5719 viewDef.defaults.duration || 5720 dynamicOptionOverrides.duration || 5721 optionOverrides.duration; 5722 var duration = null; 5723 var durationUnit = ''; 5724 var singleUnit = ''; 5725 var singleUnitOverrides = {}; 5726 if (durationInput) { 5727 duration = createDurationCached(durationInput); 5728 if (duration) { // valid? 5729 var denom = greatestDurationDenominator(duration); 5730 durationUnit = denom.unit; 5731 if (denom.value === 1) { 5732 singleUnit = durationUnit; 5733 singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {}; 5734 } 5735 } 5736 } 5737 var queryButtonText = function (optionsSubset) { 5738 var buttonTextMap = optionsSubset.buttonText || {}; 5739 var buttonTextKey = viewDef.defaults.buttonTextKey; 5740 if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) { 5741 return buttonTextMap[buttonTextKey]; 5742 } 5743 if (buttonTextMap[viewDef.type] != null) { 5744 return buttonTextMap[viewDef.type]; 5745 } 5746 if (buttonTextMap[singleUnit] != null) { 5747 return buttonTextMap[singleUnit]; 5748 } 5749 return null; 5750 }; 5751 var queryButtonTitle = function (optionsSubset) { 5752 var buttonHints = optionsSubset.buttonHints || {}; 5753 var buttonKey = viewDef.defaults.buttonTextKey; // use same key as text 5754 if (buttonKey != null && buttonHints[buttonKey] != null) { 5755 return buttonHints[buttonKey]; 5756 } 5757 if (buttonHints[viewDef.type] != null) { 5758 return buttonHints[viewDef.type]; 5759 } 5760 if (buttonHints[singleUnit] != null) { 5761 return buttonHints[singleUnit]; 5762 } 5763 return null; 5764 }; 5765 return { 5766 type: viewDef.type, 5767 component: viewDef.component, 5768 duration: duration, 5769 durationUnit: durationUnit, 5770 singleUnit: singleUnit, 5771 optionDefaults: viewDef.defaults, 5772 optionOverrides: __assign(__assign({}, singleUnitOverrides), viewDef.overrides), 5773 buttonTextOverride: queryButtonText(dynamicOptionOverrides) || 5774 queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence 5775 viewDef.overrides.buttonText, 5776 buttonTextDefault: queryButtonText(localeDefaults) || 5777 viewDef.defaults.buttonText || 5778 queryButtonText(BASE_OPTION_DEFAULTS) || 5779 viewDef.type, 5780 // not DRY 5781 buttonTitleOverride: queryButtonTitle(dynamicOptionOverrides) || 5782 queryButtonTitle(optionOverrides) || 5783 viewDef.overrides.buttonHint, 5784 buttonTitleDefault: queryButtonTitle(localeDefaults) || 5785 viewDef.defaults.buttonHint || 5786 queryButtonTitle(BASE_OPTION_DEFAULTS), 5787 // will eventually fall back to buttonText 5788 }; 5789 } 5790 // hack to get memoization working 5791 var durationInputMap = {}; 5792 function createDurationCached(durationInput) { 5793 var json = JSON.stringify(durationInput); 5794 var res = durationInputMap[json]; 5795 if (res === undefined) { 5796 res = createDuration(durationInput); 5797 durationInputMap[json] = res; 5798 } 5799 return res; 5800 } 5801 5802 var DateProfileGenerator = /** @class */ (function () { 5803 function DateProfileGenerator(props) { 5804 this.props = props; 5805 this.nowDate = getNow(props.nowInput, props.dateEnv); 5806 this.initHiddenDays(); 5807 } 5808 /* Date Range Computation 5809 ------------------------------------------------------------------------------------------------------------------*/ 5810 // Builds a structure with info about what the dates/ranges will be for the "prev" view. 5811 DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate, forceToValid) { 5812 var dateEnv = this.props.dateEnv; 5813 var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 5814 currentDateProfile.dateIncrement); 5815 return this.build(prevDate, -1, forceToValid); 5816 }; 5817 // Builds a structure with info about what the dates/ranges will be for the "next" view. 5818 DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate, forceToValid) { 5819 var dateEnv = this.props.dateEnv; 5820 var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 5821 currentDateProfile.dateIncrement); 5822 return this.build(nextDate, 1, forceToValid); 5823 }; 5824 // Builds a structure holding dates/ranges for rendering around the given date. 5825 // Optional direction param indicates whether the date is being incremented/decremented 5826 // from its previous value. decremented = -1, incremented = 1 (default). 5827 DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) { 5828 if (forceToValid === void 0) { forceToValid = true; } 5829 var props = this.props;
5830 var validRange; 5831 var currentInfo; 5832 var isRangeAllDay; 5833 var renderRange; 5834 var activeRange; 5835 var isValid; 5836 validRange = this.buildValidRange(); 5837 validRange = this.trimHiddenDays(validRange); 5838 if (forceToValid) { 5839 currentDate = constrainMarkerToRange(currentDate, validRange); 5840 } 5841 currentInfo = this.buildCurrentRangeInfo(currentDate, direction); 5842 isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit); 5843 renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay); 5844 renderRange = this.trimHiddenDays(renderRange); 5845 activeRange = renderRange; 5846 if (!props.showNonCurrentDates) { 5847 activeRange = intersectRanges(activeRange, currentInfo.range); 5848 } 5849 activeRange = this.adjustActiveRange(activeRange); 5850 activeRange = intersectRanges(activeRange, validRange); // might return null 5851 // it's invalid if the originally requested date is not contained, 5852 // or if the range is completely outside of the valid range. 5853 isValid = rangesIntersect(currentInfo.range, validRange); 5854 return { 5855 // constraint for where prev/next operations can go and where events can be dragged/resized to. 5856 // an object with optional start and end properties. 5857 validRange: validRange, 5858 // range the view is formally responsible for. 5859 // for example, a month view might have 1st-31st, excluding padded dates 5860 currentRange: currentInfo.range, 5861 // name of largest unit being displayed, like "month" or "week" 5862 currentRangeUnit: currentInfo.unit, 5863 isRangeAllDay: isRangeAllDay, 5864 // dates that display events and accept drag-n-drop 5865 // will be `null` if no dates accept events 5866 activeRange: activeRange, 5867 // date range with a rendered skeleton 5868 // includes not-active days that need some sort of DOM 5869 renderRange: renderRange, 5870 // Duration object that denotes the first visible time of any given day 5871 slotMinTime: props.slotMinTime, 5872 // Duration object that denotes the exclusive visible end time of any given day 5873 slotMaxTime: props.slotMaxTime, 5874 isValid: isValid, 5875 // how far the current date will move for a prev/next operation 5876 dateIncrement: this.buildDateIncrement(currentInfo.duration), 5877 // pass a fallback (might be null) ^ 5878 }; 5879 }; 5880 // Builds an object with optional start/end properties. 5881 // Indicates the minimum/maximum dates to display. 5882 // not responsible for trimming hidden days. 5883 DateProfileGenerator.prototype.buildValidRange = function () { 5884 var input = this.props.validRangeInput; 5885 var simpleInput = typeof input === 'function' 5886 ? input.call(this.props.calendarApi, this.nowDate) 5887 : input; 5888 return this.refineRange(simpleInput) || 5889 { start: null, end: null }; // completely open-ended 5890 }; 5891 // Builds a structure with info about the "current" range, the range that is 5892 // highlighted as being the current month for example. 5893 // See build() for a description of `direction`. 5894 // Guaranteed to have `range` and `unit` properties. `duration` is optional. 5895 DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) { 5896 var props = this.props; 5897 var duration = null; 5898 var unit = null; 5899 var range = null; 5900 var dayCount; 5901 if (props.duration) { 5902 duration = props.duration; 5903 unit = props.durationUnit; 5904 range = this.buildRangeFromDuration(date, direction, duration, unit); 5905 } 5906 else if ((dayCount = this.props.dayCount)) { 5907 unit = 'day'; 5908 range = this.buildRangeFromDayCount(date, direction, dayCount); 5909 } 5910 else if ((range = this.buildCustomVisibleRange(date))) { 5911 unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit; 5912 } 5913 else { 5914 duration = this.getFallbackDuration(); 5915 unit = greatestDurationDenominator(duration).unit; 5916 range = this.buildRangeFromDuration(date, direction, duration, unit); 5917 } 5918 return { duration: duration, unit: unit, range: range }; 5919 }; 5920 DateProfileGenerator.prototype.getFallbackDuration = function () { 5921 return createDuration({ day: 1 }); 5922 }; 5923 // Returns a new activeRange to have time values (un-ambiguate) 5924 // slotMinTime or slotMaxTime causes the range to expand. 5925 DateProfileGenerator.prototype.adjustActiveRange = function (range) { 5926 var _a = this.props, dateEnv = _a.dateEnv, usesMinMaxTime = _a.usesMinMaxTime, slotMinTime = _a.slotMinTime, slotMaxTime = _a.slotMaxTime; 5927 var start = range.start, end = range.end; 5928 if (usesMinMaxTime) { 5929 // expand active range if slotMinTime is negative (why not when positive?) 5930 if (asRoughDays(slotMinTime) < 0) { 5931 start = startOfDay(start); // necessary? 5932 start = dateEnv.add(start, slotMinTime); 5933 } 5934 // expand active range if slotMaxTime is beyond one day (why not when negative?) 5935 if (asRoughDays(slotMaxTime) > 1) { 5936 end = startOfDay(end); // necessary? 5937 end = addDays(end, -1);
5938 end = dateEnv.add(end, slotMaxTime); 5939 } 5940 } 5941 return { start: start, end: end }; 5942 }; 5943 // Builds the "current" range when it is specified as an explicit duration. 5944 // `unit` is the already-computed greatestDurationDenominator unit of duration. 5945 DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) { 5946 var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment; 5947 var start; 5948 var end; 5949 var res; 5950 // compute what the alignment should be 5951 if (!dateAlignment) { 5952 var dateIncrement = this.props.dateIncrement; 5953 if (dateIncrement) { 5954 // use the smaller of the two units 5955 if (asRoughMs(dateIncrement) < asRoughMs(duration)) { 5956 dateAlignment = greatestDurationDenominator(dateIncrement).unit; 5957 } 5958 else { 5959 dateAlignment = unit; 5960 } 5961 } 5962 else { 5963 dateAlignment = unit; 5964 } 5965 } 5966 // if the view displays a single day or smaller 5967 if (asRoughDays(duration) <= 1) { 5968 if (this.isHiddenDay(start)) { 5969 start = this.skipHiddenDays(start, direction); 5970 start = startOfDay(start); 5971 } 5972 } 5973 function computeRes() { 5974 start = dateEnv.startOf(date, dateAlignment); 5975 end = dateEnv.add(start, duration); 5976 res = { start: start, end: end }; 5977 } 5978 computeRes(); 5979 // if range is completely enveloped by hidden days, go past the hidden days 5980 if (!this.trimHiddenDays(res)) { 5981 date = this.skipHiddenDays(date, direction); 5982 computeRes(); 5983 } 5984 return res; 5985 }; 5986 // Builds the "current" range when a dayCount is specified. 5987 DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) { 5988 var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment; 5989 var runningCount = 0; 5990 var start = date; 5991 var end; 5992 if (dateAlignment) { 5993 start = dateEnv.startOf(start, dateAlignment); 5994 } 5995 start = startOfDay(start); 5996 start = this.skipHiddenDays(start, direction); 5997 end = start; 5998 do { 5999 end = addDays(end, 1); 6000 if (!this.isHiddenDay(end)) { 6001 runningCount += 1; 6002 } 6003 } while (runningCount < dayCount); 6004 return { start: start, end: end }; 6005 }; 6006 // Builds a normalized range object for the "visible" range, 6007 // which is a way to define the currentRange and activeRange at the same time. 6008 DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) { 6009 var props = this.props; 6010 var input = props.visibleRangeInput; 6011 var simpleInput = typeof input === 'function' 6012 ? input.call(props.calendarApi, props.dateEnv.toDate(date)) 6013 : input; 6014 var range = this.refineRange(simpleInput); 6015 if (range && (range.start == null || range.end == null)) { 6016 return null; 6017 } 6018 return range; 6019 }; 6020 // Computes the range that will represent the element/cells for *rendering*, 6021 // but which may have voided days/times. 6022 // not responsible for trimming hidden days. 6023 DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) { 6024 return currentRange; 6025 }; 6026 // Compute the duration value that should be added/substracted to the current date 6027 // when a prev/next operation happens. 6028 DateProfileGenerator.prototype.buildDateIncrement = function (fallback) { 6029 var dateIncrement = this.props.dateIncrement; 6030 var customAlignment; 6031 if (dateIncrement) { 6032 return dateIncrement; 6033 } 6034 if ((customAlignment = this.props.dateAlignment)) { 6035 return createDuration(1, customAlignment); 6036 } 6037 if (fallback) { 6038 return fallback; 6039 } 6040 return createDuration({ days: 1 }); 6041 }; 6042 DateProfileGenerator.prototype.refineRange = function (rangeInput) { 6043 if (rangeInput) { 6044 var range = parseRange(rangeInput, this.props.dateEnv); 6045 if (range) { 6046 range = computeVisibleDayRange(range); 6047 } 6048 return range; 6049 } 6050 return null; 6051 }; 6052 /* Hidden Days 6053 ------------------------------------------------------------------------------------------------------------------*/ 6054 // Initializes internal variables related to calculating hidden days-of-week 6055 DateProfileGenerator.prototype.initHiddenDays = function () { 6056 var hiddenDays = this.props.hiddenDays || []; // array of day-of-week indices that are hidden
6057 var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool) 6058 var dayCnt = 0; 6059 var i; 6060 if (this.props.weekends === false) { 6061 hiddenDays.push(0, 6); // 0=sunday, 6=saturday 6062 } 6063 for (i = 0; i < 7; i += 1) { 6064 if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) { 6065 dayCnt += 1; 6066 } 6067 } 6068 if (!dayCnt) { 6069 throw new Error('invalid hiddenDays'); // all days were hidden? bad. 6070 } 6071 this.isHiddenDayHash = isHiddenDayHash; 6072 }; 6073 // Remove days from the beginning and end of the range that are computed as hidden. 6074 // If the whole range is trimmed off, returns null 6075 DateProfileGenerator.prototype.trimHiddenDays = function (range) { 6076 var start = range.start, end = range.end; 6077 if (start) { 6078 start = this.skipHiddenDays(start); 6079 } 6080 if (end) { 6081 end = this.skipHiddenDays(end, -1, true); 6082 } 6083 if (start == null || end == null || start < end) { 6084 return { start: start, end: end }; 6085 } 6086 return null; 6087 }; 6088 // Is the current day hidden? 6089 // `day` is a day-of-week index (0-6), or a Date (used for UTC) 6090 DateProfileGenerator.prototype.isHiddenDay = function (day) { 6091 if (day instanceof Date) { 6092 day = day.getUTCDay(); 6093 } 6094 return this.isHiddenDayHash[day]; 6095 }; 6096 // Incrementing the current day until it is no longer a hidden day, returning a copy. 6097 // DOES NOT CONSIDER validRange! 6098 // If the initial value of `date` is not a hidden day, don't do anything. 6099 // Pass `isExclusive` as `true` if you are dealing with an end date. 6100 // `inc` defaults to `1` (increment one day forward each time) 6101 DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) { 6102 if (inc === void 0) { inc = 1; } 6103 if (isExclusive === void 0) { isExclusive = false; } 6104 while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) { 6105 date = addDays(date, inc); 6106 } 6107 return date; 6108 }; 6109 return DateProfileGenerator; 6110 }()); 6111 6112 function reduceViewType(viewType, action) { 6113 switch (action.type) { 6114 case 'CHANGE_VIEW_TYPE': 6115 viewType = action.viewType; 6116 } 6117 return viewType; 6118 } 6119 6120 function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) { 6121 var _a; 6122 switch (action.type) { 6123 case 'SET_OPTION': 6124 return __assign(__assign({}, dynamicOptionOverrides), (_a = {}, _a[action.optionName] = action.rawOptionValue, _a)); 6125 default: 6126 return dynamicOptionOverrides; 6127 } 6128 } 6129 6130 function reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) { 6131 var dp; 6132 switch (action.type) { 6133 case 'CHANGE_VIEW_TYPE': 6134 return dateProfileGenerator.build(action.dateMarker || currentDate); 6135 case 'CHANGE_DATE': 6136 return dateProfileGenerator.build(action.dateMarker); 6137 case 'PREV': 6138 dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate); 6139 if (dp.isValid) { 6140 return dp; 6141 } 6142 break; 6143 case 'NEXT': 6144 dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate); 6145 if (dp.isValid) { 6146 return dp; 6147 } 6148 break; 6149 } 6150 return currentDateProfile; 6151 } 6152 6153 function initEventSources(calendarOptions, dateProfile, context) { 6154 var activeRange = dateProfile ? dateProfile.activeRange : null; 6155 return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context); 6156 } 6157 function reduceEventSources(eventSources, action, dateProfile, context) { 6158 var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check? 6159 switch (action.type) { 6160 case 'ADD_EVENT_SOURCES': // already parsed 6161 return addSources(eventSources, action.sources, activeRange, context);
6162 case 'REMOVE_EVENT_SOURCE': 6163 return removeSource(eventSources, action.sourceId); 6164 case 'PREV': // TODO: how do we track all actions that affect dateProfile :( 6165 case 'NEXT': 6166 case 'CHANGE_DATE': 6167 case 'CHANGE_VIEW_TYPE': 6168 if (dateProfile) { 6169 return fetchDirtySources(eventSources, activeRange, context); 6170 } 6171 return eventSources; 6172 case 'FETCH_EVENT_SOURCES': 6173 return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type? 6174 arrayToHash(action.sourceIds) : 6175 excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context); 6176 case 'RECEIVE_EVENTS': 6177 case 'RECEIVE_EVENT_ERROR': 6178 return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange); 6179 case 'REMOVE_ALL_EVENT_SOURCES': 6180 return {}; 6181 default: 6182 return eventSources; 6183 } 6184 } 6185 function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) { 6186 var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check? 6187 return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context); 6188 } 6189 function computeEventSourcesLoading(eventSources) { 6190 for (var sourceId in eventSources) { 6191 if (eventSources[sourceId].isFetching) { 6192 return true; 6193 } 6194 } 6195 return false; 6196 } 6197 function addSources(eventSourceHash, sources, fetchRange, context) { 6198 var hash = {}; 6199 for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) { 6200 var source = sources_1[_i]; 6201 hash[source.sourceId] = source; 6202 } 6203 if (fetchRange) { 6204 hash = fetchDirtySources(hash, fetchRange, context); 6205 } 6206 return __assign(__assign({}, eventSourceHash), hash); 6207 } 6208 function removeSource(eventSourceHash, sourceId) { 6209 return filterHash(eventSourceHash, function (eventSource) { return eventSource.sourceId !== sourceId; }); 6210 } 6211 function fetchDirtySources(sourceHash, fetchRange, context) { 6212 return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) { return isSourceDirty(eventSource, fetchRange, context); }), fetchRange, false, context); 6213 } 6214 function isSourceDirty(eventSource, fetchRange, context) { 6215 if (!doesSourceNeedRange(eventSource, context)) { 6216 return !eventSource.latestFetchId; 6217 } 6218 return !context.options.lazyFetching || 6219 !eventSource.fetchRange || 6220 eventSource.isFetching || // always cancel outdated in-progress fetches 6221 fetchRange.start < eventSource.fetchRange.start || 6222 fetchRange.end > eventSource.fetchRange.end; 6223 } 6224 function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) { 6225 var nextSources = {}; 6226 for (var sourceId in prevSources) { 6227 var source = prevSources[sourceId]; 6228 if (sourceIdHash[sourceId]) { 6229 nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context); 6230 } 6231 else { 6232 nextSources[sourceId] = source; 6233 } 6234 } 6235 return nextSources; 6236 } 6237 function fetchSource(eventSource, fetchRange, isRefetch, context) { 6238 var options = context.options, calendarApi = context.calendarApi; 6239 var sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId]; 6240 var fetchId = guid(); 6241 sourceDef.fetch({ 6242 eventSource: eventSource, 6243 range: fetchRange, 6244 isRefetch: isRefetch, 6245 context: context, 6246 }, function (res) { 6247 var rawEvents = res.rawEvents; 6248 if (options.eventSourceSuccess) { 6249 rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.xhr) || rawEvents; 6250 } 6251 if (eventSource.success) { 6252 rawEvents = eventSource.success.call(calendarApi, rawEvents, res.xhr) || rawEvents; 6253 } 6254 context.dispatch({ 6255 type: 'RECEIVE_EVENTS', 6256 sourceId: eventSource.sourceId, 6257 fetchId: fetchId, 6258 fetchRange: fetchRange, 6259 rawEvents: rawEvents, 6260 }); 6261 }, function (error) { 6262 console.warn(error.message, error); 6263 if (options.eventSourceFailure) { 6264 options.eventSourceFailure.call(calendarApi, error); 6265 } 6266 if (eventSource.failure) { 6267 eventSource.failure(error); 6268 } 6269 context.dispatch({ 6270 type: 'RECEIVE_EVENT_ERROR', 6271 sourceId: eventSource.sourceId, 6272 fetchId: fetchId, 6273 fetchRange: fetchRange, 6274 error: error, 6275 }); 6276 }); 6277 return __assign(__assign({}, eventSource), { isFetching: true, latestFetchId: fetchId }); 6278 } 6279 function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) { 6280 var _a; 6281 var eventSource = sourceHash[sourceId]; 6282 if (eventSource && // not already removed 6283 fetchId === eventSource.latestFetchId) { 6284 return __assign(__assign({}, sourceHash), (_a = {}, _a[sourceId] = __assign(__assign({}, eventSource), { isFetching: false, fetchRange: fetchRange }), _a)); 6285 } 6286 return sourceHash; 6287 } 6288 function excludeStaticSources(eventSources, context) { 6289 return filterHash(eventSources, function (eventSource) { return doesSourceNeedRange(eventSource, context); }); 6290 } 6291 function parseInitialSources(rawOptions, context) { 6292 var refiners = buildEventSourceRefiners(context); 6293 var rawSources = [].concat(rawOptions.eventSources || []); 6294 var sources = []; // parsed 6295 if (rawOptions.initialEvents) { 6296 rawSources.unshift(rawOptions.initialEvents); 6297 } 6298 if (rawOptions.events) { 6299 rawSources.unshift(rawOptions.events); 6300 } 6301 for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) { 6302 var rawSource = rawSources_1[_i]; 6303 var source = parseEventSource(rawSource, context, refiners); 6304 if (source) { 6305 sources.push(source); 6306 } 6307 } 6308 return sources; 6309 } 6310 function doesSourceNeedRange(eventSource, context) { 6311 var defs = context.pluginHooks.eventSourceDefs; 6312 return !defs[eventSource.sourceDefId].ignoreRange; 6313 } 6314 6315 function reduceEventStore(eventStore, action, eventSources, dateProfile, context) { 6316 switch (action.type) { 6317 case 'RECEIVE_EVENTS': // raw 6318 return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context); 6319 case 'ADD_EVENTS': // already parsed, but not expanded 6320 return addEvent(eventStore, action.eventStore, // new ones 6321 dateProfile ? dateProfile.activeRange : null, context); 6322 case 'RESET_EVENTS': 6323 return action.eventStore; 6324 case 'MERGE_EVENTS': // already parsed and expanded 6325 return mergeEventStores(eventStore, action.eventStore); 6326 case 'PREV': // TODO: how do we track all actions that affect dateProfile :( 6327 case 'NEXT': 6328 case 'CHANGE_DATE': 6329 case 'CHANGE_VIEW_TYPE': 6330 if (dateProfile) { 6331 return expandRecurring(eventStore, dateProfile.activeRange, context); 6332 } 6333 return eventStore;
6334 case 'REMOVE_EVENTS': 6335 return excludeSubEventStore(eventStore, action.eventStore); 6336 case 'REMOVE_EVENT_SOURCE': 6337 return excludeEventsBySourceId(eventStore, action.sourceId); 6338 case 'REMOVE_ALL_EVENT_SOURCES': 6339 return filterEventStoreDefs(eventStore, function (eventDef) { return (!eventDef.sourceId // only keep events with no source id 6340 ); }); 6341 case 'REMOVE_ALL_EVENTS': 6342 return createEmptyEventStore(); 6343 default: 6344 return eventStore; 6345 } 6346 } 6347 function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) { 6348 if (eventSource && // not already removed 6349 fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources 6350 ) { 6351 var subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context); 6352 if (fetchRange) { 6353 subset = expandRecurring(subset, fetchRange, context); 6354 } 6355 return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset); 6356 } 6357 return eventStore; 6358 } 6359 function transformRawEvents(rawEvents, eventSource, context) { 6360 var calEachTransform = context.options.eventDataTransform; 6361 var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null; 6362 if (sourceEachTransform) { 6363 rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform); 6364 } 6365 if (calEachTransform) { 6366 rawEvents = transformEachRawEvent(rawEvents, calEachTransform); 6367 } 6368 return rawEvents; 6369 } 6370 function transformEachRawEvent(rawEvents, func) { 6371 var refinedEvents; 6372 if (!func) { 6373 refinedEvents = rawEvents; 6374 } 6375 else { 6376 refinedEvents = []; 6377 for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) { 6378 var rawEvent = rawEvents_1[_i]; 6379 var refinedEvent = func(rawEvent); 6380 if (refinedEvent) { 6381 refinedEvents.push(refinedEvent); 6382 } 6383 else if (refinedEvent == null) { 6384 refinedEvents.push(rawEvent); 6385 } // if a different falsy value, do nothing 6386 } 6387 } 6388 return refinedEvents; 6389 } 6390 function addEvent(eventStore, subset, expandRange, context) { 6391 if (expandRange) { 6392 subset = expandRecurring(subset, expandRange, context); 6393 } 6394 return mergeEventStores(eventStore, subset); 6395 } 6396 function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) { 6397 var defs = eventStore.defs; 6398 var instances = mapHash(eventStore.instances, function (instance) { 6399 var def = defs[instance.defId]; 6400 if (def.allDay || def.recurringDef) { 6401 return instance; // isn't dependent on timezone 6402 } 6403 return __assign(__assign({}, instance), { range: { 6404 start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)), 6405 end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo)), 6406 }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo }); 6407 }); 6408 return { defs: defs, instances: instances }; 6409 } 6410 function excludeEventsBySourceId(eventStore, sourceId) { 6411 return filterEventStoreDefs(eventStore, function (eventDef) { return eventDef.sourceId !== sourceId; }); 6412 } 6413 // QUESTION: why not just return instances? do a general object-property-exclusion util 6414 function excludeInstances(eventStore, removals) { 6415 return { 6416 defs: eventStore.defs, 6417 instances: filterHash(eventStore.instances, function (instance) { return !removals[instance.instanceId]; }), 6418 }; 6419 } 6420 6421 function reduceDateSelection(currentSelection, action) { 6422 switch (action.type) { 6423 case 'UNSELECT_DATES': 6424 return null; 6425 case 'SELECT_DATES': 6426 return action.selection; 6427 default: 6428 return currentSelection; 6429 } 6430 } 6431 6432 function reduceSelectedEvent(currentInstanceId, action) { 6433 switch (action.type) { 6434 case 'UNSELECT_EVENT': 6435 return ''; 6436 case 'SELECT_EVENT': 6437 return action.eventInstanceId; 6438 default: 6439 return currentInstanceId; 6440 } 6441 } 6442 6443 function reduceEventDrag(currentDrag, action) { 6444 var newDrag; 6445 switch (action.type) { 6446 case 'UNSET_EVENT_DRAG': 6447 return null; 6448 case 'SET_EVENT_DRAG': 6449 newDrag = action.state; 6450 return { 6451 affectedEvents: newDrag.affectedEvents, 6452 mutatedEvents: newDrag.mutatedEvents, 6453 isEvent: newDrag.isEvent, 6454 }; 6455 default: 6456 return currentDrag; 6457 } 6458 } 6459 6460 function reduceEventResize(currentResize, action) { 6461 var newResize; 6462 switch (action.type) { 6463 case 'UNSET_EVENT_RESIZE': 6464 return null; 6465 case 'SET_EVENT_RESIZE': 6466 newResize = action.state; 6467 return { 6468 affectedEvents: newResize.affectedEvents, 6469 mutatedEvents: newResize.mutatedEvents, 6470 isEvent: newResize.isEvent, 6471 }; 6472 default: 6473 return currentResize; 6474 } 6475 } 6476 6477 function parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) { 6478 var header = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null; 6479 var footer = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null; 6480 return { header: header, footer: footer }; 6481 } 6482 function parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) { 6483 var sectionWidgets = {}; 6484 var viewsWithButtons = []; 6485 var hasTitle = false; 6486 for (var sectionName in sectionStrHash) { 6487 var sectionStr = sectionStrHash[sectionName]; 6488 var sectionRes = parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi); 6489 sectionWidgets[sectionName] = sectionRes.widgets; 6490 viewsWithButtons.push.apply(viewsWithButtons, sectionRes.viewsWithButtons); 6491 hasTitle = hasTitle || sectionRes.hasTitle; 6492 } 6493 return { sectionWidgets: sectionWidgets, viewsWithButtons: viewsWithButtons, hasTitle: hasTitle }; 6494 } 6495 /* 6496 BAD: querying icons and text here. should be done at render time 6497 */ 6498 function parseSection(sectionStr, calendarOptions, // defaults+overrides, then refined 6499 calendarOptionOverrides, // overrides only!, unrefined :( 6500 theme, viewSpecs, calendarApi) { 6501 var isRtl = calendarOptions.direction === 'rtl'; 6502 var calendarCustomButtons = calendarOptions.customButtons || {}; 6503 var calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {}; 6504 var calendarButtonText = calendarOptions.buttonText || {}; 6505 var calendarButtonHintOverrides = calendarOptionOverrides.buttonHints || {}; 6506 var calendarButtonHints = calendarOptions.buttonHints || {}; 6507 var sectionSubstrs = sectionStr ? sectionStr.split(' ') : []; 6508 var viewsWithButtons = []; 6509 var hasTitle = false; 6510 var widgets = sectionSubstrs.map(function (buttonGroupStr) { return (buttonGroupStr.split(',').map(function (buttonName) { 6511 if (buttonName === 'title') { 6512 hasTitle = true; 6513 return { buttonName: buttonName }; 6514 } 6515 var customButtonProps; 6516 var viewSpec; 6517 var buttonClick; 6518 var buttonIcon; // only one of these will be set 6519 var buttonText; // " 6520 var buttonHint; 6521 // ^ for the title="" attribute, for accessibility 6522 if ((customButtonProps = calendarCustomButtons[buttonName])) { 6523 buttonClick = function (ev) { 6524 if (customButtonProps.click) { 6525 customButtonProps.click.call(ev.target, ev, ev.target); // TODO: use Calendar this context? 6526 } 6527 }; 6528 (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) || 6529 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6530 (buttonText = customButtonProps.text); 6531 buttonHint = customButtonProps.hint || customButtonProps.text; 6532 } 6533 else if ((viewSpec = viewSpecs[buttonName])) { 6534 viewsWithButtons.push(buttonName); 6535 buttonClick = function () { 6536 calendarApi.changeView(buttonName); 6537 }; 6538 (buttonText = viewSpec.buttonTextOverride) || 6539 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6540 (buttonText = viewSpec.buttonTextDefault); 6541 var textFallback = viewSpec.buttonTextOverride || 6542 viewSpec.buttonTextDefault; 6543 buttonHint = formatWithOrdinals(viewSpec.buttonTitleOverride || 6544 viewSpec.buttonTitleDefault || 6545 calendarOptions.viewHint, [textFallback, buttonName], // view-name = buttonName 6546 textFallback); 6547 } 6548 else if (calendarApi[buttonName]) { // a calendarApi method 6549 buttonClick = function () { 6550 calendarApi[buttonName](); 6551 }; 6552 (buttonText = calendarButtonTextOverrides[buttonName]) || 6553 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6554 (buttonText = calendarButtonText[buttonName]); // everything else is considered default 6555 if (buttonName === 'prevYear' || buttonName === 'nextYear') { 6556 var prevOrNext = buttonName === 'prevYear' ? 'prev' : 'next'; 6557 buttonHint = formatWithOrdinals(calendarButtonHintOverrides[prevOrNext] || 6558 calendarButtonHints[prevOrNext], [ 6559 calendarButtonText.year || 'year', 6560 'year', 6561 ], calendarButtonText[buttonName]); 6562 } 6563 else { 6564 buttonHint = function (navUnit) { return formatWithOrdinals(calendarButtonHintOverrides[buttonName] || 6565 calendarButtonHints[buttonName], [ 6566 calendarButtonText[navUnit] || navUnit, 6567 navUnit, 6568 ], calendarButtonText[buttonName]); }; 6569 } 6570 } 6571 return { buttonName: buttonName, buttonClick: buttonClick, buttonIcon: buttonIcon, buttonText: buttonText, buttonHint: buttonHint }; 6572 })); }); 6573 return { widgets: widgets, viewsWithButtons: viewsWithButtons, hasTitle: hasTitle }; 6574 } 6575 6576 var eventSourceDef$3 = { 6577 ignoreRange: true, 6578 parseMeta: function (refined) { 6579 if (Array.isArray(refined.events)) { 6580 return refined.events; 6581 } 6582 return null; 6583 }, 6584 fetch: function (arg, success) { 6585 success({ 6586 rawEvents: arg.eventSource.meta, 6587 }); 6588 }, 6589 }; 6590 var arrayEventSourcePlugin = createPlugin({ 6591 eventSourceDefs: [eventSourceDef$3], 6592 });
6593 6594 var eventSourceDef$2 = { 6595 parseMeta: function (refined) { 6596 if (typeof refined.events === 'function') { 6597 return refined.events; 6598 } 6599 return null; 6600 }, 6601 fetch: function (arg, success, failure) { 6602 var dateEnv = arg.context.dateEnv; 6603 var func = arg.eventSource.meta; 6604 unpromisify(func.bind(null, buildRangeApiWithTimeZone(arg.range, dateEnv)), function (rawEvents) { 6605 success({ rawEvents: rawEvents }); // needs an object response 6606 }, failure); 6607 }, 6608 }; 6609 var funcEventSourcePlugin = createPlugin({ 6610 eventSourceDefs: [eventSourceDef$2], 6611 }); 6612 6613 function requestJson(method, url, params, successCallback, failureCallback) { 6614 method = method.toUpperCase(); 6615 var body = null; 6616 if (method === 'GET') { 6617 url = injectQueryStringParams(url, params); 6618 } 6619 else { 6620 body = encodeParams(params); 6621 } 6622 var xhr = new XMLHttpRequest(); 6623 xhr.open(method, url, true); 6624 if (method !== 'GET') { 6625 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 6626 } 6627 xhr.onload = function () { 6628 if (xhr.status >= 200 && xhr.status < 400) { 6629 var parsed = false; 6630 var res = void 0; 6631 try { 6632 res = JSON.parse(xhr.responseText); 6633 parsed = true; 6634 } 6635 catch (err) { 6636 // will handle parsed=false 6637 } 6638 if (parsed) { 6639 successCallback(res, xhr); 6640 } 6641 else { 6642 failureCallback('Failure parsing JSON', xhr); 6643 } 6644 } 6645 else { 6646 failureCallback('Request failed', xhr); 6647 } 6648 }; 6649 xhr.onerror = function () { 6650 failureCallback('Request failed', xhr); 6651 }; 6652 xhr.send(body); 6653 } 6654 function injectQueryStringParams(url, params) { 6655 return url + 6656 (url.indexOf('?') === -1 ? '?' : '&') + 6657 encodeParams(params); 6658 } 6659 function encodeParams(params) { 6660 var parts = []; 6661 for (var key in params) { 6662 parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key])); 6663 } 6664 return parts.join('&'); 6665 } 6666 6667 var JSON_FEED_EVENT_SOURCE_REFINERS = { 6668 method: String, 6669 extraParams: identity, 6670 startParam: String, 6671 endParam: String, 6672 timeZoneParam: String, 6673 }; 6674 6675 var eventSourceDef$1 = { 6676 parseMeta: function (refined) { 6677 if (refined.url && (refined.format === 'json' || !refined.format)) { 6678 return { 6679 url: refined.url, 6680 format: 'json', 6681 method: (refined.method || 'GET').toUpperCase(), 6682 extraParams: refined.extraParams, 6683 startParam: refined.startParam, 6684 endParam: refined.endParam, 6685 timeZoneParam: refined.timeZoneParam, 6686 }; 6687 } 6688 return null; 6689 }, 6690 fetch: function (arg, success, failure) { 6691 var meta = arg.eventSource.meta; 6692 var requestParams = buildRequestParams$1(meta, arg.range, arg.context); 6693 requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) { 6694 success({ rawEvents: rawEvents, xhr: xhr }); 6695 }, function (errorMessage, xhr) { 6696 failure({ message: errorMessage, xhr: xhr }); 6697 }); 6698 }, 6699 }; 6700 var jsonFeedEventSourcePlugin = createPlugin({ 6701 eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS, 6702 eventSourceDefs: [eventSourceDef$1], 6703 }); 6704 function buildRequestParams$1(meta, range, context) { 6705 var dateEnv = context.dateEnv, options = context.options; 6706 var startParam; 6707 var endParam; 6708 var timeZoneParam;
6709 var customRequestParams; 6710 var params = {}; 6711 startParam = meta.startParam; 6712 if (startParam == null) { 6713 startParam = options.startParam; 6714 } 6715 endParam = meta.endParam; 6716 if (endParam == null) { 6717 endParam = options.endParam; 6718 } 6719 timeZoneParam = meta.timeZoneParam; 6720 if (timeZoneParam == null) { 6721 timeZoneParam = options.timeZoneParam; 6722 } 6723 // retrieve any outbound GET/POST data from the options 6724 if (typeof meta.extraParams === 'function') { 6725 // supplied as a function that returns a key/value object 6726 customRequestParams = meta.extraParams(); 6727 } 6728 else { 6729 // probably supplied as a straight key/value object 6730 customRequestParams = meta.extraParams || {}; 6731 } 6732 __assign(params, customRequestParams); 6733 params[startParam] = dateEnv.formatIso(range.start); 6734 params[endParam] = dateEnv.formatIso(range.end); 6735 if (dateEnv.timeZone !== 'local') { 6736 params[timeZoneParam] = dateEnv.timeZone; 6737 } 6738 return params; 6739 } 6740 6741 var SIMPLE_RECURRING_REFINERS = { 6742 daysOfWeek: identity, 6743 startTime: createDuration, 6744 endTime: createDuration, 6745 duration: createDuration, 6746 startRecur: identity, 6747 endRecur: identity, 6748 }; 6749 6750 var recurring = { 6751 parse: function (refined, dateEnv) { 6752 if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) { 6753 var recurringData = { 6754 daysOfWeek: refined.daysOfWeek || null, 6755 startTime: refined.startTime || null, 6756 endTime: refined.endTime || null, 6757 startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null, 6758 endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null, 6759 }; 6760 var duration = void 0; 6761 if (refined.duration) { 6762 duration = refined.duration; 6763 } 6764 if (!duration && refined.startTime && refined.endTime) { 6765 duration = subtractDurations(refined.endTime, refined.startTime); 6766 } 6767 return { 6768 allDayGuess: Boolean(!refined.startTime && !refined.endTime), 6769 duration: duration, 6770 typeData: recurringData, // doesn't need endTime anymore but oh well 6771 }; 6772 } 6773 return null; 6774 }, 6775 expand: function (typeData, framingRange, dateEnv) { 6776 var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur }); 6777 if (clippedFramingRange) { 6778 return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv); 6779 } 6780 return []; 6781 }, 6782 }; 6783 var simpleRecurringEventsPlugin = createPlugin({ 6784 recurringTypes: [recurring], 6785 eventRefiners: SIMPLE_RECURRING_REFINERS, 6786 }); 6787 function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) { 6788 var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null; 6789 var dayMarker = startOfDay(framingRange.start); 6790 var endMarker = framingRange.end; 6791 var instanceStarts = []; 6792 while (dayMarker < endMarker) { 6793 var instanceStart 6794 // if everyday, or this particular day-of-week 6795 = void 0; 6796 // if everyday, or this particular day-of-week 6797 if (!dowHash || dowHash[dayMarker.getUTCDay()]) { 6798 if (startTime) { 6799 instanceStart = dateEnv.add(dayMarker, startTime); 6800 } 6801 else { 6802 instanceStart = dayMarker; 6803 } 6804 instanceStarts.push(instanceStart); 6805 } 6806 dayMarker = addDays(dayMarker, 1); 6807 } 6808 return instanceStarts; 6809 } 6810 6811 var changeHandlerPlugin = createPlugin({ 6812 optionChangeHandlers: { 6813 events: function (events, context) { 6814 handleEventSources([events], context); 6815 }, 6816 eventSources: handleEventSources, 6817 }, 6818 });
6819 /* 6820 BUG: if `event` was supplied, all previously-given `eventSources` will be wiped out 6821 */ 6822 function handleEventSources(inputs, context) { 6823 var unfoundSources = hashValuesToArray(context.getCurrentData().eventSources); 6824 var newInputs = []; 6825 for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) { 6826 var input = inputs_1[_i]; 6827 var inputFound = false; 6828 for (var i = 0; i < unfoundSources.length; i += 1) { 6829 if (unfoundSources[i]._raw === input) { 6830 unfoundSources.splice(i, 1); // delete 6831 inputFound = true; 6832 break; 6833 } 6834 } 6835 if (!inputFound) { 6836 newInputs.push(input); 6837 } 6838 } 6839 for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) { 6840 var unfoundSource = unfoundSources_1[_a]; 6841 context.dispatch({ 6842 type: 'REMOVE_EVENT_SOURCE', 6843 sourceId: unfoundSource.sourceId, 6844 }); 6845 } 6846 for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) { 6847 var newInput = newInputs_1[_b]; 6848 context.calendarApi.addEventSource(newInput); 6849 } 6850 } 6851 6852 function handleDateProfile(dateProfile, context) { 6853 context.emitter.trigger('datesSet', __assign(__assign({}, buildRangeApiWithTimeZone(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi })); 6854 } 6855 6856 function handleEventStore(eventStore, context) { 6857 var emitter = context.emitter; 6858 if (emitter.hasHandlers('eventsSet')) { 6859 emitter.trigger('eventsSet', buildEventApis(eventStore, context)); 6860 } 6861 } 6862 6863 /* 6864 this array is exposed on the root namespace so that UMD plugins can add to it. 6865 see the rollup-bundles script. 6866 */ 6867 var globalPlugins = [ 6868 arrayEventSourcePlugin, 6869 funcEventSourcePlugin, 6870 jsonFeedEventSourcePlugin, 6871 simpleRecurringEventsPlugin, 6872 changeHandlerPlugin, 6873 createPlugin({ 6874 isLoadingFuncs: [ 6875 function (state) { return computeEventSourcesLoading(state.eventSources); }, 6876 ], 6877 contentTypeHandlers: { 6878 html: buildHtmlRenderer, 6879 domNodes: buildDomNodeRenderer, 6880 }, 6881 propSetHandlers: { 6882 dateProfile: handleDateProfile, 6883 eventStore: handleEventStore, 6884 }, 6885 }), 6886 ]; 6887 function buildHtmlRenderer() { 6888 var currentEl = null; 6889 var currentHtml = ''; 6890 function render(el, html) { 6891 if (el !== currentEl || html !== currentHtml) { 6892 el.innerHTML = html; 6893 } 6894 currentEl = el; 6895 currentHtml = html; 6896 } 6897 function destroy() { 6898 currentEl.innerHTML = ''; 6899 currentEl = null; 6900 currentHtml = ''; 6901 } 6902 return { render: render, destroy: destroy }; 6903 } 6904 function buildDomNodeRenderer() { 6905 var currentEl = null; 6906 var currentDomNodes = []; 6907 function render(el, domNodes) { 6908 var newDomNodes = Array.prototype.slice.call(domNodes); 6909 if (el !== currentEl || !isArraysEqual(currentDomNodes, newDomNodes)) { 6910 // append first, remove second (for scroll resetting) 6911 for (var _i = 0, newDomNodes_1 = newDomNodes; _i < newDomNodes_1.length; _i++) { 6912 var newNode = newDomNodes_1[_i]; 6913 el.appendChild(newNode); 6914 } 6915 destroy(); 6916 } 6917 currentEl = el; 6918 currentDomNodes = newDomNodes; 6919 } 6920 function destroy() { 6921 currentDomNodes.forEach(removeElement); 6922 currentDomNodes = []; 6923 currentEl = null; 6924 } 6925 return { render: render, destroy: destroy }; 6926 } 6927 6928 var DelayedRunner = /** @class */ (function () { 6929 function DelayedRunner(drainedOption) { 6930 this.drainedOption = drainedOption; 6931 this.isRunning = false; 6932 this.isDirty = false; 6933 this.pauseDepths = {}; 6934 this.timeoutId = 0; 6935 } 6936 DelayedRunner.prototype.request = function (delay) { 6937 this.isDirty = true; 6938 if (!this.isPaused()) { 6939 this.clearTimeout(); 6940 if (delay == null) { 6941 this.tryDrain(); 6942 } 6943 else { 6944 this.timeoutId = setTimeout(// NOT OPTIMAL! TODO: look at debounce 6945 this.tryDrain.bind(this), delay); 6946 } 6947 } 6948 }; 6949 DelayedRunner.prototype.pause = function (scope) { 6950 if (scope === void 0) { scope = ''; } 6951 var pauseDepths = this.pauseDepths; 6952 pauseDepths[scope] = (pauseDepths[scope] || 0) + 1; 6953 this.clearTimeout(); 6954 }; 6955 DelayedRunner.prototype.resume = function (scope, force) { 6956 if (scope === void 0) { scope = ''; } 6957 var pauseDepths = this.pauseDepths; 6958 if (scope in pauseDepths) { 6959 if (force) { 6960 delete pauseDepths[scope]; 6961 } 6962 else { 6963 pauseDepths[scope] -= 1; 6964 var depth = pauseDepths[scope]; 6965 if (depth <= 0) { 6966 delete pauseDepths[scope]; 6967 } 6968 } 6969 this.tryDrain(); 6970 } 6971 }; 6972 DelayedRunner.prototype.isPaused = function () { 6973 return Object.keys(this.pauseDepths).length; 6974 }; 6975 DelayedRunner.prototype.tryDrain = function () { 6976 if (!this.isRunning && !this.isPaused()) { 6977 this.isRunning = true; 6978 while (this.isDirty) { 6979 this.isDirty = false; 6980 this.drained(); // might set isDirty to true again 6981 } 6982 this.isRunning = false; 6983 } 6984 }; 6985 DelayedRunner.prototype.clear = function () { 6986 this.clearTimeout(); 6987 this.isDirty = false; 6988 this.pauseDepths = {}; 6989 }; 6990 DelayedRunner.prototype.clearTimeout = function () { 6991 if (this.timeoutId) { 6992 clearTimeout(this.timeoutId); 6993 this.timeoutId = 0; 6994 } 6995 }; 6996 DelayedRunner.prototype.drained = function () { 6997 if (this.drainedOption) { 6998 this.drainedOption(); 6999 } 7000 }; 7001 return DelayedRunner; 7002 }()); 7003 7004 var TaskRunner = /** @class */ (function () { 7005 function TaskRunner(runTaskOption, drainedOption) { 7006 this.runTaskOption = runTaskOption; 7007 this.drainedOption = drainedOption; 7008 this.queue = []; 7009 this.delayedRunner = new DelayedRunner(this.drain.bind(this)); 7010 } 7011 TaskRunner.prototype.request = function (task, delay) { 7012 this.queue.push(task); 7013 this.delayedRunner.request(delay); 7014 }; 7015 TaskRunner.prototype.pause = function (scope) { 7016 this.delayedRunner.pause(scope); 7017 }; 7018 TaskRunner.prototype.resume = function (scope, force) { 7019 this.delayedRunner.resume(scope, force); 7020 };
7021 TaskRunner.prototype.drain = function () { 7022 var queue = this.queue; 7023 while (queue.length) { 7024 var completedTasks = []; 7025 var task = void 0; 7026 while ((task = queue.shift())) { 7027 this.runTask(task); 7028 completedTasks.push(task); 7029 } 7030 this.drained(completedTasks); 7031 } // keep going, in case new tasks were added in the drained handler 7032 }; 7033 TaskRunner.prototype.runTask = function (task) { 7034 if (this.runTaskOption) { 7035 this.runTaskOption(task); 7036 } 7037 }; 7038 TaskRunner.prototype.drained = function (completedTasks) { 7039 if (this.drainedOption) { 7040 this.drainedOption(completedTasks); 7041 } 7042 }; 7043 return TaskRunner; 7044 }()); 7045 7046 // Computes what the title at the top of the calendarApi should be for this view 7047 function buildTitle(dateProfile, viewOptions, dateEnv) { 7048 var range; 7049 // for views that span a large unit of time, show the proper interval, ignoring stray days before and after 7050 if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) { 7051 range = dateProfile.currentRange; 7052 } 7053 else { // for day units or smaller, use the actual day range 7054 range = dateProfile.activeRange; 7055 } 7056 return dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || buildTitleFormat(dateProfile)), { 7057 isEndExclusive: dateProfile.isRangeAllDay, 7058 defaultSeparator: viewOptions.titleRangeSeparator, 7059 }); 7060 } 7061 // Generates the format string that should be used to generate the title for the current date range. 7062 // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`. 7063 function buildTitleFormat(dateProfile) { 7064 var currentRangeUnit = dateProfile.currentRangeUnit; 7065 if (currentRangeUnit === 'year') { 7066 return { year: 'numeric' }; 7067 } 7068 if (currentRangeUnit === 'month') { 7069 return { year: 'numeric', month: 'long' }; // like "September 2014" 7070 } 7071 var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end); 7072 if (days !== null && days > 1) { 7073 // multi-day range. shorter, like "Sep 9 - 10 2014" 7074 return { year: 'numeric', month: 'short', day: 'numeric' }; 7075 } 7076 // one day. longer, like "September 9 2014" 7077 return { year: 'numeric', month: 'long', day: 'numeric' }; 7078 } 7079 7080 // in future refactor, do the redux-style function(state=initial) for initial-state 7081 // also, whatever is happening in constructor, have it happen in action queue too 7082 var CalendarDataManager = /** @class */ (function () { 7083 function CalendarDataManager(props) { 7084 var _this = this; 7085 this.computeOptionsData = memoize(this._computeOptionsData); 7086 this.computeCurrentViewData = memoize(this._computeCurrentViewData); 7087 this.organizeRawLocales = memoize(organizeRawLocales); 7088 this.buildLocale = memoize(buildLocale); 7089 this.buildPluginHooks = buildBuildPluginHooks(); 7090 this.buildDateEnv = memoize(buildDateEnv); 7091 this.buildTheme = memoize(buildTheme); 7092 this.parseToolbars = memoize(parseToolbars); 7093 this.buildViewSpecs = memoize(buildViewSpecs); 7094 this.buildDateProfileGenerator = memoizeObjArg(buildDateProfileGenerator); 7095 this.buildViewApi = memoize(buildViewApi); 7096 this.buildViewUiProps = memoizeObjArg(buildViewUiProps); 7097 this.buildEventUiBySource = memoize(buildEventUiBySource, isPropsEqual); 7098 this.buildEventUiBases = memoize(buildEventUiBases); 7099 this.parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours); 7100 this.buildTitle = memoize(buildTitle); 7101 this.emitter = new Emitter(); 7102 this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this)); 7103 this.currentCalendarOptionsInput = {}; 7104 this.currentCalendarOptionsRefined = {}; 7105 this.currentViewOptionsInput = {}; 7106 this.currentViewOptionsRefined = {}; 7107 this.currentCalendarOptionsRefiners = {}; 7108 this.getCurrentData = function () { return _this.data; }; 7109 this.dispatch = function (action) { 7110 _this.actionRunner.request(action); // protects against recursive calls to _handleAction 7111 }; 7112 this.props = props; 7113 this.actionRunner.pause(); 7114 var dynamicOptionOverrides = {}; 7115 var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi); 7116 var currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView; 7117 var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides); 7118 // wire things up 7119 // TODO: not DRY 7120 props.calendarApi.currentDataManager = this; 7121 this.emitter.setThisContext(props.calendarApi); 7122 this.emitter.setOptions(currentViewData.options); 7123 var currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv); 7124 var dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 7125 if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) { 7126 currentDate = dateProfile.currentRange.start; 7127 } 7128 var calendarContext = { 7129 dateEnv: optionsData.dateEnv, 7130 options: optionsData.calendarOptions, 7131 pluginHooks: optionsData.pluginHooks, 7132 calendarApi: props.calendarApi, 7133 dispatch: this.dispatch, 7134 emitter: this.emitter, 7135 getCurrentData: this.getCurrentData, 7136 }; 7137 // needs to be after setThisContext 7138 for (var _i = 0, _a = optionsData.pluginHooks.contextInit; _i < _a.length; _i++) { 7139 var callback = _a[_i]; 7140 callback(calendarContext); 7141 } 7142 // NOT DRY 7143 var eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext); 7144 var initialState = { 7145 dynamicOptionOverrides: dynamicOptionOverrides, 7146 currentViewType: currentViewType, 7147 currentDate: currentDate, 7148 dateProfile: dateProfile, 7149 businessHours: this.parseContextBusinessHours(calendarContext), 7150 eventSources: eventSources, 7151 eventUiBases: {}, 7152 eventStore: createEmptyEventStore(), 7153 renderableEventStore: createEmptyEventStore(), 7154 dateSelection: null, 7155 eventSelection: '', 7156 eventDrag: null, 7157 eventResize: null, 7158 selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig, 7159 }; 7160 var contextAndState = __assign(__assign({}, calendarContext), initialState); 7161 for (var _b = 0, _c = optionsData.pluginHooks.reducers; _b < _c.length; _b++) { 7162 var reducer = _c[_b]; 7163 __assign(initialState, reducer(null, null, contextAndState)); 7164 } 7165 if (computeIsLoading(initialState, calendarContext)) { 7166 this.emitter.trigger('loading', true); // NOT DRY 7167 } 7168 this.state = initialState; 7169 this.updateData(); 7170 this.actionRunner.resume(); 7171 } 7172 CalendarDataManager.prototype.resetOptions = function (optionOverrides, append) { 7173 var props = this.props; 7174 props.optionOverrides = append 7175 ? __assign(__assign({}, props.optionOverrides), optionOverrides) : optionOverrides; 7176 this.actionRunner.request({ 7177 type: 'NOTHING', 7178 }); 7179 }; 7180 CalendarDataManager.prototype._handleAction = function (action) { 7181 var _a = this, props = _a.props, state = _a.state, emitter = _a.emitter; 7182 var dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action); 7183 var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi); 7184 var currentViewType = reduceViewType(state.currentViewType, action); 7185 var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides); 7186 // wire things up 7187 // TODO: not DRY 7188 props.calendarApi.currentDataManager = this; 7189 emitter.setThisContext(props.calendarApi); 7190 emitter.setOptions(currentViewData.options); 7191 var calendarContext = { 7192 dateEnv: optionsData.dateEnv, 7193 options: optionsData.calendarOptions, 7194 pluginHooks: optionsData.pluginHooks, 7195 calendarApi: props.calendarApi, 7196 dispatch: this.dispatch, 7197 emitter: emitter, 7198 getCurrentData: this.getCurrentData, 7199 }; 7200 var currentDate = state.currentDate, dateProfile = state.dateProfile; 7201 if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack 7202 dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 7203 } 7204 currentDate = reduceCurrentDate(currentDate, action); 7205 dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator); 7206 if (action.type === 'PREV' || // TODO: move this logic into DateProfileGenerator 7207 action.type === 'NEXT' || // " 7208 !rangeContainsMarker(dateProfile.currentRange, currentDate)) { 7209 currentDate = dateProfile.currentRange.start; 7210 } 7211 var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext); 7212 var eventStore = reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendarContext); 7213 var isEventsLoading = computeEventSourcesLoading(eventSources);
7213 // BAD. also called in this func in computeIsLoading 7214 var renderableEventStore = (isEventsLoading && !currentViewData.options.progressiveEventRendering) ? 7215 (state.renderableEventStore || eventStore) : // try from previous state 7216 eventStore; 7217 var _b = this.buildViewUiProps(calendarContext), eventUiSingleBase = _b.eventUiSingleBase, selectionConfig = _b.selectionConfig; // will memoize obj 7218 var eventUiBySource = this.buildEventUiBySource(eventSources); 7219 var eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource); 7220 var newState = { 7221 dynamicOptionOverrides: dynamicOptionOverrides, 7222 currentViewType: currentViewType, 7223 currentDate: currentDate, 7224 dateProfile: dateProfile, 7225 eventSources: eventSources, 7226 eventStore: eventStore, 7227 renderableEventStore: renderableEventStore, 7228 selectionConfig: selectionConfig, 7229 eventUiBases: eventUiBases, 7230 businessHours: this.parseContextBusinessHours(calendarContext), 7231 dateSelection: reduceDateSelection(state.dateSelection, action), 7232 eventSelection: reduceSelectedEvent(state.eventSelection, action), 7233 eventDrag: reduceEventDrag(state.eventDrag, action), 7234 eventResize: reduceEventResize(state.eventResize, action), 7235 }; 7236 var contextAndState = __assign(__assign({}, calendarContext), newState); 7237 for (var _i = 0, _c = optionsData.pluginHooks.reducers; _i < _c.length; _i++) { 7238 var reducer = _c[_i]; 7239 __assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value 7240 } 7241 var wasLoading = computeIsLoading(state, calendarContext); 7242 var isLoading = computeIsLoading(newState, calendarContext); 7243 // TODO: use propSetHandlers in plugin system 7244 if (!wasLoading && isLoading) { 7245 emitter.trigger('loading', true); 7246 } 7247 else if (wasLoading && !isLoading) { 7248 emitter.trigger('loading', false); 7249 } 7250 this.state = newState; 7251 if (props.onAction) { 7252 props.onAction(action); 7253 } 7254 }; 7255 CalendarDataManager.prototype.updateData = function () { 7256 var _a = this, props = _a.props, state = _a.state; 7257 var oldData = this.data; 7258 var optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi); 7259 var currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides); 7260 var data = this.data = __assign(__assign(__assign({ viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state); 7261 var changeHandlers = optionsData.pluginHooks.optionChangeHandlers; 7262 var oldCalendarOptions = oldData && oldData.calendarOptions; 7263 var newCalendarOptions = optionsData.calendarOptions; 7264 if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) { 7265 if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) { 7266 // hack 7267 state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data); 7268 state.eventStore = data.eventStore = rezoneEventStoreDates(data.eventStore, oldData.dateEnv, data.dateEnv); 7269 } 7270 for (var optionName in changeHandlers) { 7271 if (oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) { 7272 changeHandlers[optionName](newCalendarOptions[optionName], data); 7273 } 7274 } 7275 } 7276 if (props.onData) { 7277 props.onData(data); 7278 } 7279 }; 7280 CalendarDataManager.prototype._computeOptionsData = function (optionOverrides, dynamicOptionOverrides, calendarApi) { 7281 // TODO: blacklist options that are handled by optionChangeHandlers 7282 var _a = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, pluginHooks = _a.pluginHooks, localeDefaults = _a.localeDefaults, availableLocaleData = _a.availableLocaleData, extra = _a.extra; 7283 warnUnknownOptions(extra); 7284 var dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator); 7285 var viewSpecs = this.buildViewSpecs(pluginHooks.views, optionOverrides, dynamicOptionOverrides, localeDefaults); 7286 var theme = this.buildTheme(refinedOptions, pluginHooks); 7287 var toolbarConfig = this.parseToolbars(refinedOptions, optionOverrides, theme, viewSpecs, calendarApi); 7288 return { 7289 calendarOptions: refinedOptions, 7290 pluginHooks: pluginHooks, 7291 dateEnv: dateEnv, 7292 viewSpecs: viewSpecs, 7293 theme: theme, 7294 toolbarConfig: toolbarConfig, 7295 localeDefaults: localeDefaults, 7296 availableRawLocales: availableLocaleData.map, 7297 }; 7298 }; 7299 // always called from behind a memoizer 7300 CalendarDataManager.prototype.processRawCalendarOptions = function (optionOverrides, dynamicOptionOverrides) { 7301 var _a = mergeRawOptions([ 7302 BASE_OPTION_DEFAULTS, 7303 optionOverrides, 7304 dynamicOptionOverrides, 7305 ]), locales = _a.locales, locale = _a.locale; 7306 var availableLocaleData = this.organizeRawLocales(locales); 7307 var availableRawLocales = availableLocaleData.map; 7308 var localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options; 7309 var pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins); 7310 var refiners = this.currentCalendarOptionsRefiners = __assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners); 7311 var extra = {}; 7312 var raw = mergeRawOptions([ 7313 BASE_OPTION_DEFAULTS, 7314 localeDefaults, 7315 optionOverrides, 7316 dynamicOptionOverrides, 7317 ]);
7318 var refined = {}; 7319 var currentRaw = this.currentCalendarOptionsInput; 7320 var currentRefined = this.currentCalendarOptionsRefined; 7321 var anyChanges = false; 7322 for (var optionName in raw) { 7323 if (optionName !== 'plugins') { // because plugins is special-cased 7324 if (raw[optionName] === currentRaw[optionName] || 7325 (COMPLEX_OPTION_COMPARATORS[optionName] && 7326 (optionName in currentRaw) && 7327 COMPLEX_OPTION_COMPARATORS[optionName](currentRaw[optionName], raw[optionName]))) { 7328 refined[optionName] = currentRefined[optionName]; 7329 } 7330 else if (refiners[optionName]) { 7331 refined[optionName] = refiners[optionName](raw[optionName]); 7332 anyChanges = true; 7333 } 7334 else { 7335 extra[optionName] = currentRaw[optionName]; 7336 } 7337 } 7338 } 7339 if (anyChanges) { 7340 this.currentCalendarOptionsInput = raw; 7341 this.currentCalendarOptionsRefined = refined; 7342 } 7343 return { 7344 rawOptions: this.currentCalendarOptionsInput, 7345 refinedOptions: this.currentCalendarOptionsRefined, 7346 pluginHooks: pluginHooks, 7347 availableLocaleData: availableLocaleData, 7348 localeDefaults: localeDefaults, 7349 extra: extra, 7350 }; 7351 }; 7352 CalendarDataManager.prototype._computeCurrentViewData = function (viewType, optionsData, optionOverrides, dynamicOptionOverrides) { 7353 var viewSpec = optionsData.viewSpecs[viewType]; 7354 if (!viewSpec) { 7355 throw new Error("viewType \"" + viewType + "\" is not available. Please make sure you've loaded all neccessary plugins"); 7356 } 7357 var _a = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, extra = _a.extra; 7358 warnUnknownOptions(extra); 7359 var dateProfileGenerator = this.buildDateProfileGenerator({ 7360 dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass, 7361 duration: viewSpec.duration, 7362 durationUnit: viewSpec.durationUnit, 7363 usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime, 7364 dateEnv: optionsData.dateEnv, 7365 calendarApi: this.props.calendarApi, 7366 slotMinTime: refinedOptions.slotMinTime, 7367 slotMaxTime: refinedOptions.slotMaxTime, 7368 showNonCurrentDates: refinedOptions.showNonCurrentDates, 7369 dayCount: refinedOptions.dayCount, 7370 dateAlignment: refinedOptions.dateAlignment, 7371 dateIncrement: refinedOptions.dateIncrement, 7372 hiddenDays: refinedOptions.hiddenDays, 7373 weekends: refinedOptions.weekends, 7374 nowInput: refinedOptions.now, 7375 validRangeInput: refinedOptions.validRange, 7376 visibleRangeInput: refinedOptions.visibleRange, 7377 monthMode: refinedOptions.monthMode, 7378 fixedWeekCount: refinedOptions.fixedWeekCount, 7379 }); 7380 var viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv); 7381 return { viewSpec: viewSpec, options: refinedOptions, dateProfileGenerator: dateProfileGenerator, viewApi: viewApi }; 7382 }; 7383 CalendarDataManager.prototype.processRawViewOptions = function (viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) { 7384 var raw = mergeRawOptions([ 7385 BASE_OPTION_DEFAULTS, 7386 viewSpec.optionDefaults, 7387 localeDefaults, 7388 optionOverrides, 7389 viewSpec.optionOverrides, 7390 dynamicOptionOverrides, 7391 ]); 7392 var refiners = __assign(__assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), VIEW_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
7393 var refined = {}; 7394 var currentRaw = this.currentViewOptionsInput; 7395 var currentRefined = this.currentViewOptionsRefined; 7396 var anyChanges = false; 7397 var extra = {}; 7398 for (var optionName in raw) { 7399 if (raw[optionName] === currentRaw[optionName]) { 7400 refined[optionName] = currentRefined[optionName]; 7401 } 7402 else { 7403 if (raw[optionName] === this.currentCalendarOptionsInput[optionName]) { 7404 if (optionName in this.currentCalendarOptionsRefined) { // might be an "extra" prop 7405 refined[optionName] = this.currentCalendarOptionsRefined[optionName]; 7406 } 7407 } 7408 else if (refiners[optionName]) { 7409 refined[optionName] = refiners[optionName](raw[optionName]); 7410 } 7411 else { 7412 extra[optionName] = raw[optionName]; 7413 } 7414 anyChanges = true; 7415 } 7416 } 7417 if (anyChanges) { 7418 this.currentViewOptionsInput = raw; 7419 this.currentViewOptionsRefined = refined; 7420 } 7421 return { 7422 rawOptions: this.currentViewOptionsInput, 7423 refinedOptions: this.currentViewOptionsRefined, 7424 extra: extra, 7425 }; 7426 }; 7427 return CalendarDataManager; 7428 }()); 7429 function buildDateEnv(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) { 7430 var locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map); 7431 return new DateEnv({ 7432 calendarSystem: 'gregory', 7433 timeZone: timeZone, 7434 namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl, 7435 locale: locale, 7436 weekNumberCalculation: weekNumberCalculation, 7437 firstDay: firstDay, 7438 weekText: weekText, 7439 cmdFormatter: pluginHooks.cmdFormatter, 7440 defaultSeparator: defaultSeparator, 7441 }); 7442 } 7443 function buildTheme(options, pluginHooks) { 7444 var ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme; 7445 return new ThemeClass(options); 7446 } 7447 function buildDateProfileGenerator(props) { 7448 var DateProfileGeneratorClass = props.dateProfileGeneratorClass || DateProfileGenerator; 7449 return new DateProfileGeneratorClass(props); 7450 } 7451 function buildViewApi(type, getCurrentData, dateEnv) { 7452 return new ViewApi(type, getCurrentData, dateEnv); 7453 } 7454 function buildEventUiBySource(eventSources) { 7455 return mapHash(eventSources, function (eventSource) { return eventSource.ui; }); 7456 } 7457 function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) { 7458 var eventUiBases = { '': eventUiSingleBase }; 7459 for (var defId in eventDefs) { 7460 var def = eventDefs[defId]; 7461 if (def.sourceId && eventUiBySource[def.sourceId]) { 7462 eventUiBases[defId] = eventUiBySource[def.sourceId]; 7463 } 7464 } 7465 return eventUiBases; 7466 } 7467 function buildViewUiProps(calendarContext) { 7468 var options = calendarContext.options; 7469 return { 7470 eventUiSingleBase: createEventUi({ 7471 display: options.eventDisplay, 7472 editable: options.editable, 7473 startEditable: options.eventStartEditable, 7474 durationEditable: options.eventDurationEditable, 7475 constraint: options.eventConstraint, 7476 overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined, 7477 allow: options.eventAllow, 7478 backgroundColor: options.eventBackgroundColor, 7479 borderColor: options.eventBorderColor, 7480 textColor: options.eventTextColor, 7481 color: options.eventColor, 7482 // classNames: options.eventClassNames // render hook will handle this 7483 }, calendarContext), 7484 selectionConfig: createEventUi({ 7485 constraint: options.selectConstraint, 7486 overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined, 7487 allow: options.selectAllow, 7488 }, calendarContext), 7489 }; 7490 } 7491 function computeIsLoading(state, context) { 7492 for (var _i = 0, _a = context.pluginHooks.isLoadingFuncs; _i < _a.length; _i++) { 7493 var isLoadingFunc = _a[_i]; 7494 if (isLoadingFunc(state)) { 7495 return true; 7496 } 7497 } 7498 return false; 7499 } 7500 function parseContextBusinessHours(calendarContext) { 7501 return parseBusinessHours(calendarContext.options.businessHours, calendarContext); 7502 } 7503 function warnUnknownOptions(options, viewName) { 7504 for (var optionName in options) { 7505 console.warn("Unknown option '" + optionName + "'" + 7506 (viewName ? " for view '" + viewName + "'" : '')); 7507 } 7508 } 7509 7510 // TODO: move this to react plugin? 7511 var CalendarDataProvider = /** @class */ (function (_super) { 7512 __extends(CalendarDataProvider, _super); 7513 function CalendarDataProvider(props) { 7514 var _this = _super.call(this, props) || this; 7515 _this.handleData = function (data) { 7516 if (!_this.dataManager) { // still within initial run, before assignment in constructor 7517 // eslint-disable-next-line react/no-direct-mutation-state 7518 _this.state = data; // can't use setState yet 7519 } 7520 else { 7521 _this.setState(data); 7522 } 7523 }; 7524 _this.dataManager = new CalendarDataManager({ 7525 optionOverrides: props.optionOverrides, 7526 calendarApi: props.calendarApi, 7527 onData: _this.handleData, 7528 }); 7529 return _this; 7530 } 7531 CalendarDataProvider.prototype.render = function () { 7532 return this.props.children(this.state); 7533 }; 7534 CalendarDataProvider.prototype.componentDidUpdate = function (prevProps) { 7535 var newOptionOverrides = this.props.optionOverrides; 7536 if (newOptionOverrides !== prevProps.optionOverrides) { // prevent recursive handleData 7537 this.dataManager.resetOptions(newOptionOverrides); 7538 } 7539 }; 7540 return CalendarDataProvider; 7541 }(Component)); 7542 7543 // HELPERS 7544 /* 7545 if nextDayThreshold is specified, slicing is done in an all-day fashion. 7546 you can get nextDayThreshold from context.nextDayThreshold 7547 */ 7548 function sliceEvents(props, allDay) { 7549 return sliceEventStore(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg; 7550 } 7551 7552 var NamedTimeZoneImpl = /** @class */ (function () { 7553 function NamedTimeZoneImpl(timeZoneName) { 7554 this.timeZoneName = timeZoneName; 7555 } 7556 return NamedTimeZoneImpl; 7557 }()); 7558 7559 var SegHierarchy = /** @class */ (function () { 7560 function SegHierarchy() { 7561 // settings 7562 this.strictOrder = false; 7563 this.allowReslicing = false; 7564 this.maxCoord = -1; // -1 means no max 7565 this.maxStackCnt = -1; // -1 means no max 7566 this.levelCoords = []; // ordered 7567 this.entriesByLevel = []; // parallel with levelCoords 7568 this.stackCnts = {}; // TODO: use better technique!? 7569 } 7570 SegHierarchy.prototype.addSegs = function (inputs) { 7571 var hiddenEntries = [];
7572 for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) { 7573 var input = inputs_1[_i]; 7574 this.insertEntry(input, hiddenEntries); 7575 } 7576 return hiddenEntries; 7577 }; 7578 SegHierarchy.prototype.insertEntry = function (entry, hiddenEntries) { 7579 var insertion = this.findInsertion(entry); 7580 if (this.isInsertionValid(insertion, entry)) { 7581 this.insertEntryAt(entry, insertion); 7582 return 1; 7583 } 7584 return this.handleInvalidInsertion(insertion, entry, hiddenEntries); 7585 }; 7586 SegHierarchy.prototype.isInsertionValid = function (insertion, entry) { 7587 return (this.maxCoord === -1 || insertion.levelCoord + entry.thickness <= this.maxCoord) && 7588 (this.maxStackCnt === -1 || insertion.stackCnt < this.maxStackCnt); 7589 }; 7590 // returns number of new entries inserted 7591 SegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) { 7592 if (this.allowReslicing && insertion.touchingEntry) { 7593 return this.splitEntry(entry, insertion.touchingEntry, hiddenEntries); 7594 } 7595 hiddenEntries.push(entry); 7596 return 0; 7597 }; 7598 SegHierarchy.prototype.splitEntry = function (entry, barrier, hiddenEntries) { 7599 var partCnt = 0; 7600 var splitHiddenEntries = []; 7601 var entrySpan = entry.span; 7602 var barrierSpan = barrier.span; 7603 if (entrySpan.start < barrierSpan.start) { 7604 partCnt += this.insertEntry({ 7605 index: entry.index, 7606 thickness: entry.thickness, 7607 span: { start: entrySpan.start, end: barrierSpan.start }, 7608 }, splitHiddenEntries); 7609 } 7610 if (entrySpan.end > barrierSpan.end) { 7611 partCnt += this.insertEntry({ 7612 index: entry.index, 7613 thickness: entry.thickness, 7614 span: { start: barrierSpan.end, end: entrySpan.end }, 7615 }, splitHiddenEntries); 7616 } 7617 if (partCnt) { 7618 hiddenEntries.push.apply(hiddenEntries, __spreadArray([{ 7619 index: entry.index, 7620 thickness: entry.thickness, 7621 span: intersectSpans(barrierSpan, entrySpan), // guaranteed to intersect 7622 }], splitHiddenEntries)); 7623 return partCnt; 7624 } 7625 hiddenEntries.push(entry); 7626 return 0; 7627 }; 7628 SegHierarchy.prototype.insertEntryAt = function (entry, insertion) { 7629 var _a = this, entriesByLevel = _a.entriesByLevel, levelCoords = _a.levelCoords; 7630 if (insertion.lateral === -1) { 7631 // create a new level 7632 insertAt(levelCoords, insertion.level, insertion.levelCoord); 7633 insertAt(entriesByLevel, insertion.level, [entry]); 7634 } 7635 else { 7636 // insert into existing level 7637 insertAt(entriesByLevel[insertion.level], insertion.lateral, entry); 7638 } 7639 this.stackCnts[buildEntryKey(entry)] = insertion.stackCnt; 7640 }; 7641 SegHierarchy.prototype.findInsertion = function (newEntry) { 7642 var _a = this, levelCoords = _a.levelCoords, entriesByLevel = _a.entriesByLevel, strictOrder = _a.strictOrder, stackCnts = _a.stackCnts; 7643 var levelCnt = levelCoords.length; 7644 var candidateCoord = 0; 7645 var touchingLevel = -1; 7646 var touchingLateral = -1; 7647 var touchingEntry = null; 7648 var stackCnt = 0; 7649 for (var trackingLevel = 0; trackingLevel < levelCnt; trackingLevel += 1) { 7650 var trackingCoord = levelCoords[trackingLevel]; 7651 // if the current level is past the placed entry, we have found a good empty space and can stop. 7652 // if strictOrder, keep finding more lateral intersections. 7653 if (!strictOrder && trackingCoord >= candidateCoord + newEntry.thickness) { 7654 break; 7655 } 7656 var trackingEntries = entriesByLevel[trackingLevel]; 7657 var trackingEntry = void 0; 7658 var searchRes = binarySearch(trackingEntries, newEntry.span.start, getEntrySpanEnd);
7658 // find first entry after newEntry's end 7659 var lateralIndex = searchRes[0] + searchRes[1]; // if exact match (which doesn't collide), go to next one 7660 while ( // loop through entries that horizontally intersect 7661 (trackingEntry = trackingEntries[lateralIndex]) && // but not past the whole entry list 7662 trackingEntry.span.start < newEntry.span.end // and not entirely past newEntry 7663 ) { 7664 var trackingEntryBottom = trackingCoord + trackingEntry.thickness; 7665 // intersects into the top of the candidate? 7666 if (trackingEntryBottom > candidateCoord) { 7667 candidateCoord = trackingEntryBottom; 7668 touchingEntry = trackingEntry; 7669 touchingLevel = trackingLevel; 7670 touchingLateral = lateralIndex; 7671 } 7672 // butts up against top of candidate? (will happen if just intersected as well) 7673 if (trackingEntryBottom === candidateCoord) { 7674 // accumulate the highest possible stackCnt of the trackingEntries that butt up 7675 stackCnt = Math.max(stackCnt, stackCnts[buildEntryKey(trackingEntry)] + 1); 7676 } 7677 lateralIndex += 1;
7678 } 7679 } 7680 // the destination level will be after touchingEntry's level. find it 7681 var destLevel = 0; 7682 if (touchingEntry) { 7683 destLevel = touchingLevel + 1; 7684 while (destLevel < levelCnt && levelCoords[destLevel] < candidateCoord) { 7685 destLevel += 1; 7686 } 7687 } 7688 // if adding to an existing level, find where to insert 7689 var destLateral = -1; 7690 if (destLevel < levelCnt && levelCoords[destLevel] === candidateCoord) { 7691 destLateral = binarySearch(entriesByLevel[destLevel], newEntry.span.end, getEntrySpanEnd)[0]; 7692 } 7693 return { 7694 touchingLevel: touchingLevel, 7695 touchingLateral: touchingLateral, 7696 touchingEntry: touchingEntry, 7697 stackCnt: stackCnt, 7698 levelCoord: candidateCoord, 7699 level: destLevel, 7700 lateral: destLateral, 7701 }; 7702 }; 7703 // sorted by levelCoord (lowest to highest) 7704 SegHierarchy.prototype.toRects = function () { 7705 var _a = this, entriesByLevel = _a.entriesByLevel, levelCoords = _a.levelCoords; 7706 var levelCnt = entriesByLevel.length; 7707 var rects = []; 7708 for (var level = 0; level < levelCnt; level += 1) { 7709 var entries = entriesByLevel[level]; 7710 var levelCoord = levelCoords[level]; 7711 for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { 7712 var entry = entries_1[_i]; 7713 rects.push(__assign(__assign({}, entry), { levelCoord: levelCoord })); 7714 } 7715 } 7716 return rects; 7717 }; 7718 return SegHierarchy; 7719 }()); 7720 function getEntrySpanEnd(entry) { 7721 return entry.span.end; 7722 } 7723 function buildEntryKey(entry) { 7724 return entry.index + ':' + entry.span.start; 7725 } 7726 // returns groups with entries sorted by input order 7727 function groupIntersectingEntries(entries) { 7728 var merges = []; 7729 for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { 7730 var entry = entries_2[_i]; 7731 var filteredMerges = []; 7732 var hungryMerge = { 7733 span: entry.span, 7734 entries: [entry], 7735 }; 7736 for (var _a = 0, merges_1 = merges; _a < merges_1.length; _a++) { 7737 var merge = merges_1[_a]; 7738 if (intersectSpans(merge.span, hungryMerge.span)) { 7739 hungryMerge = { 7740 entries: merge.entries.concat(hungryMerge.entries), 7741 span: joinSpans(merge.span, hungryMerge.span), 7742 }; 7743 } 7744 else { 7745 filteredMerges.push(merge); 7746 } 7747 } 7748 filteredMerges.push(hungryMerge); 7749 merges = filteredMerges; 7750 } 7751 return merges; 7752 } 7753 function joinSpans(span0, span1) { 7754 return { 7755 start: Math.min(span0.start, span1.start), 7756 end: Math.max(span0.end, span1.end), 7757 }; 7758 } 7759 function intersectSpans(span0, span1) { 7760 var start = Math.max(span0.start, span1.start); 7761 var end = Math.min(span0.end, span1.end); 7762 if (start < end) { 7763 return { start: start, end: end }; 7764 } 7765 return null; 7766 } 7767 // general util 7768 // --------------------------------------------------------------------------------------------------------------------- 7769 function insertAt(arr, index, item) { 7770 arr.splice(index, 0, item); 7771 } 7772 function binarySearch(a, searchVal, getItemVal) { 7773 var startIndex = 0; 7774 var endIndex = a.length; // exclusive 7775 if (!endIndex || searchVal < getItemVal(a[startIndex])) { // no items OR before first item 7776 return [0, 0]; 7777 } 7778 if (searchVal > getItemVal(a[endIndex - 1])) { // after last item 7779 return [endIndex, 0]; 7780 } 7781 while (startIndex < endIndex) { 7782 var middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2);
7783 var middleVal = getItemVal(a[middleIndex]); 7784 if (searchVal < middleVal) { 7785 endIndex = middleIndex; 7786 } 7787 else if (searchVal > middleVal) { 7788 startIndex = middleIndex + 1; 7789 } 7790 else { // equal! 7791 return [middleIndex, 1]; 7792 } 7793 } 7794 return [startIndex, 0]; 7795 } 7796 7797 var Interaction = /** @class */ (function () { 7798 function Interaction(settings) { 7799 this.component = settings.component; 7800 this.isHitComboAllowed = settings.isHitComboAllowed || null; 7801 } 7802 Interaction.prototype.destroy = function () { 7803 }; 7804 return Interaction; 7805 }()); 7806 function parseInteractionSettings(component, input) { 7807 return { 7808 component: component, 7809 el: input.el, 7810 useEventCenter: input.useEventCenter != null ? input.useEventCenter : true, 7811 isHitComboAllowed: input.isHitComboAllowed || null, 7812 }; 7813 } 7814 function interactionSettingsToStore(settings) { 7815 var _a; 7816 return _a = {}, 7817 _a[settings.component.uid] = settings, 7818 _a; 7819 } 7820 // global state 7821 var interactionSettingsStore = {}; 7822 7823 /* 7824 An abstraction for a dragging interaction originating on an event. 7825 Does higher-level things than PointerDragger, such as possibly: 7826 - a "mirror" that moves with the pointer 7827 - a minimum number of pixels or other criteria for a true drag to begin 7828 7829 subclasses must emit: 7830 - pointerdown 7831 - dragstart 7832 - dragmove 7833 - pointerup 7834 - dragend 7835 */ 7836 var ElementDragging = /** @class */ (function () { 7837 function ElementDragging(el, selector) { 7838 this.emitter = new Emitter(); 7839 } 7840 ElementDragging.prototype.destroy = function () { 7841 }; 7842 ElementDragging.prototype.setMirrorIsVisible = function (bool) { 7843 // optional if subclass doesn't want to support a mirror 7844 }; 7845 ElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 7846 // optional if subclass doesn't want to support a mirror 7847 }; 7848 ElementDragging.prototype.setAutoScrollEnabled = function (bool) { 7849 // optional 7850 }; 7851 return ElementDragging; 7852 }()); 7853 7854 // TODO: get rid of this in favor of options system, 7855 // tho it's really easy to access this globally rather than pass thru options. 7856 var config = {}; 7857 7858 /* 7859 Information about what will happen when an external element is dragged-and-dropped 7860 onto a calendar. Contains information for creating an event. 7861 */ 7862 var DRAG_META_REFINERS = { 7863 startTime: createDuration, 7864 duration: createDuration, 7865 create: Boolean, 7866 sourceId: String, 7867 }; 7868 function parseDragMeta(raw) { 7869 var _a = refineProps(raw, DRAG_META_REFINERS), refined = _a.refined, extra = _a.extra; 7870 return { 7871 startTime: refined.startTime || null, 7872 duration: refined.duration || null, 7873 create: refined.create != null ? refined.create : true, 7874 sourceId: refined.sourceId, 7875 leftoverProps: extra, 7876 }; 7877 } 7878 7879 var ToolbarSection = /** @class */ (function (_super) { 7880 __extends(ToolbarSection, _super); 7881 function ToolbarSection() { 7882 return _super !== null && _super.apply(this, arguments) || this; 7883 } 7884 ToolbarSection.prototype.render = function () { 7885 var _this = this; 7886 var children = this.props.widgetGroups.map(function (widgetGroup) { return _this.renderWidgetGroup(widgetGroup); }); 7887 return createElement.apply(void 0, __spreadArray(['div', { className: 'fc-toolbar-chunk' }], children)); 7888 }; 7889 ToolbarSection.prototype.renderWidgetGroup = function (widgetGroup) { 7890 var props = this.props; 7891 var theme = this.context.theme; 7892 var children = []; 7893 var isOnlyButtons = true; 7894 for (var _i = 0, widgetGroup_1 = widgetGroup; _i < widgetGroup_1.length; _i++) { 7895 var widget = widgetGroup_1[_i]; 7896 var buttonName = widget.buttonName, buttonClick = widget.buttonClick, buttonText = widget.buttonText, buttonIcon = widget.buttonIcon, buttonHint = widget.buttonHint; 7897 if (buttonName === 'title') { 7898 isOnlyButtons = false; 7899 children.push(createElement("h2", { className: "fc-toolbar-title", id: props.titleId }, props.title)); 7900 } 7901 else { 7902 var isPressed = buttonName === props.activeButton; 7903 var isDisabled = (!props.isTodayEnabled && buttonName === 'today') || 7904 (!props.isPrevEnabled && buttonName === 'prev') || 7905 (!props.isNextEnabled && buttonName === 'next');
7906 var buttonClasses = ["fc-" + buttonName + "-button", theme.getClass('button')]; 7907 if (isPressed) { 7908 buttonClasses.push(theme.getClass('buttonActive')); 7909 } 7910 children.push(createElement("button", { type: "button", title: typeof buttonHint === 'function' ? buttonHint(props.navUnit) : buttonHint, disabled: isDisabled, "aria-pressed": isPressed, className: buttonClasses.join(' '), onClick: buttonClick }, buttonText || (buttonIcon ? createElement("span", { className: buttonIcon }) : ''))); 7911 } 7912 } 7913 if (children.length > 1) { 7914 var groupClassName = (isOnlyButtons && theme.getClass('buttonGroup')) || ''; 7915 return createElement.apply(void 0, __spreadArray(['div', { className: groupClassName }], children)); 7916 } 7917 return children[0]; 7918 }; 7919 return ToolbarSection; 7920 }(BaseComponent)); 7921 7922 var Toolbar = /** @class */ (function (_super) { 7923 __extends(Toolbar, _super); 7924 function Toolbar() { 7925 return _super !== null && _super.apply(this, arguments) || this; 7926 } 7927 Toolbar.prototype.render = function () { 7928 var _a = this.props, model = _a.model, extraClassName = _a.extraClassName; 7929 var forceLtr = false; 7930 var startContent; 7931 var endContent; 7932 var sectionWidgets = model.sectionWidgets; 7933 var centerContent = sectionWidgets.center; 7934 if (sectionWidgets.left) { 7935 forceLtr = true; 7936 startContent = sectionWidgets.left; 7937 } 7938 else { 7939 startContent = sectionWidgets.start; 7940 } 7941 if (sectionWidgets.right) { 7942 forceLtr = true; 7943 endContent = sectionWidgets.right; 7944 } 7945 else { 7946 endContent = sectionWidgets.end; 7947 } 7948 var classNames = [ 7949 extraClassName || '', 7950 'fc-toolbar', 7951 forceLtr ? 'fc-toolbar-ltr' : '', 7952 ]; 7953 return (createElement("div", { className: classNames.join(' ') }, 7954 this.renderSection('start', startContent || []), 7955 this.renderSection('center', centerContent || []), 7956 this.renderSection('end', endContent || []))); 7957 }; 7958 Toolbar.prototype.renderSection = function (key, widgetGroups) { 7959 var props = this.props; 7960 return (createElement(ToolbarSection, { key: key, widgetGroups: widgetGroups, title: props.title, navUnit: props.navUnit, activeButton: props.activeButton, isTodayEnabled: props.isTodayEnabled, isPrevEnabled: props.isPrevEnabled, isNextEnabled: props.isNextEnabled, titleId: props.titleId })); 7961 }; 7962 return Toolbar; 7963 }(BaseComponent)); 7964 7965 // TODO: do function component? 7966 var ViewContainer = /** @class */ (function (_super) { 7967 __extends(ViewContainer, _super); 7968 function ViewContainer() { 7969 var _this = _super !== null && _super.apply(this, arguments) || this; 7970 _this.state = { 7971 availableWidth: null, 7972 }; 7973 _this.handleEl = function (el) { 7974 _this.el = el; 7975 setRef(_this.props.elRef, el); 7976 _this.updateAvailableWidth(); 7977 }; 7978 _this.handleResize = function () { 7979 _this.updateAvailableWidth(); 7980 }; 7981 return _this; 7982 } 7983 ViewContainer.prototype.render = function () { 7984 var _a = this, props = _a.props, state = _a.state; 7985 var aspectRatio = props.aspectRatio; 7986 var classNames = [ 7987 'fc-view-harness', 7988 (aspectRatio || props.liquid || props.height) 7989 ? 'fc-view-harness-active' // harness controls the height 7990 : 'fc-view-harness-passive', // let the view do the height 7991 ]; 7992 var height = ''; 7993 var paddingBottom = ''; 7994 if (aspectRatio) { 7995 if (state.availableWidth !== null) { 7996 height = state.availableWidth / aspectRatio; 7997 } 7998 else { 7999 // while waiting to know availableWidth, we can't set height to *zero* 8000 // because will cause lots of unnecessary scrollbars within scrollgrid. 8001 // BETTER: don't start rendering ANYTHING yet until we know container width 8002 // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606) 8003 paddingBottom = (1 / aspectRatio) * 100 + "%"; 8004 } 8005 } 8006 else { 8007 height = props.height || ''; 8008 } 8009 return (createElement("div", { "aria-labelledby": props.labeledById, ref: this.handleEl, className: classNames.join(' '), style: { height: height, paddingBottom: paddingBottom } }, props.children)); 8010 }; 8011 ViewContainer.prototype.componentDidMount = function () { 8012 this.context.addResizeHandler(this.handleResize); 8013 }; 8014 ViewContainer.prototype.componentWillUnmount = function () { 8015 this.context.removeResizeHandler(this.handleResize); 8016 }; 8017 ViewContainer.prototype.updateAvailableWidth = function () { 8018 if (this.el && // needed. but why? 8019 this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth 8020 ) { 8021 this.setState({ availableWidth: this.el.offsetWidth }); 8022 } 8023 }; 8024 return ViewContainer; 8025 }(BaseComponent)); 8026 8027 /* 8028 Detects when the user clicks on an event within a DateComponent 8029 */ 8030 var EventClicking = /** @class */ (function (_super) { 8031 __extends(EventClicking, _super);
8032 function EventClicking(settings) { 8033 var _this = _super.call(this, settings) || this; 8034 _this.handleSegClick = function (ev, segEl) { 8035 var component = _this.component; 8036 var context = component.context; 8037 var seg = getElSeg(segEl); 8038 if (seg && // might be the <div> surrounding the more link 8039 component.isValidSegDownEl(ev.target)) { 8040 // our way to simulate a link click for elements that can't be <a> tags 8041 // grab before trigger fired in case trigger trashes DOM thru rerendering 8042 var hasUrlContainer = elementClosest(ev.target, '.fc-event-forced-url'); 8043 var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : ''; 8044 context.emitter.trigger('eventClick', { 8045 el: segEl, 8046 event: new EventApi(component.context, seg.eventRange.def, seg.eventRange.instance), 8047 jsEvent: ev, 8048 view: context.viewApi, 8049 }); 8050 if (url && !ev.defaultPrevented) { 8051 window.location.href = url; 8052 } 8053 } 8054 }; 8055 _this.destroy = listenBySelector(settings.el, 'click', '.fc-event', // on both fg and bg events 8056 _this.handleSegClick); 8057 return _this; 8058 } 8059 return EventClicking; 8060 }(Interaction)); 8061 8062 /* 8063 Triggers events and adds/removes core classNames when the user's pointer 8064 enters/leaves event-elements of a component. 8065 */ 8066 var EventHovering = /** @class */ (function (_super) { 8067 __extends(EventHovering, _super); 8068 function EventHovering(settings) { 8069 var _this = _super.call(this, settings) || this; 8070 // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it 8071 _this.handleEventElRemove = function (el) { 8072 if (el === _this.currentSegEl) { 8073 _this.handleSegLeave(null, _this.currentSegEl); 8074 } 8075 }; 8076 _this.handleSegEnter = function (ev, segEl) { 8077 if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper 8078 _this.currentSegEl = segEl; 8079 _this.triggerEvent('eventMouseEnter', ev, segEl); 8080 } 8081 }; 8082 _this.handleSegLeave = function (ev, segEl) { 8083 if (_this.currentSegEl) { 8084 _this.currentSegEl = null; 8085 _this.triggerEvent('eventMouseLeave', ev, segEl); 8086 } 8087 }; 8088 _this.removeHoverListeners = listenToHoverBySelector(settings.el, '.fc-event', // on both fg and bg events 8089 _this.handleSegEnter, _this.handleSegLeave); 8090 return _this; 8091 } 8092 EventHovering.prototype.destroy = function () { 8093 this.removeHoverListeners(); 8094 }; 8095 EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) { 8096 var component = this.component; 8097 var context = component.context; 8098 var seg = getElSeg(segEl); 8099 if (!ev || component.isValidSegDownEl(ev.target)) { 8100 context.emitter.trigger(publicEvName, { 8101 el: segEl, 8102 event: new EventApi(context, seg.eventRange.def, seg.eventRange.instance), 8103 jsEvent: ev, 8104 view: context.viewApi, 8105 }); 8106 } 8107 }; 8108 return EventHovering; 8109 }(Interaction)); 8110 8111 var CalendarContent = /** @class */ (function (_super) { 8112 __extends(CalendarContent, _super); 8113 function CalendarContent() { 8114 var _this = _super !== null && _super.apply(this, arguments) || this; 8115 _this.buildViewContext = memoize(buildViewContext); 8116 _this.buildViewPropTransformers = memoize(buildViewPropTransformers); 8117 _this.buildToolbarProps = memoize(buildToolbarProps); 8118 _this.headerRef = createRef(); 8119 _this.footerRef = createRef(); 8120 _this.interactionsStore = {}; 8121 // eslint-disable-next-line 8122 _this.state = { 8123 viewLabelId: getUniqueDomId(), 8124 }; 8125 // Component Registration 8126 // ----------------------------------------------------------------------------------------------------------------- 8127 _this.registerInteractiveComponent = function (component, settingsInput) { 8128 var settings = parseInteractionSettings(component, settingsInput); 8129 var DEFAULT_INTERACTIONS = [ 8130 EventClicking, 8131 EventHovering, 8132 ]; 8133 var interactionClasses = DEFAULT_INTERACTIONS.concat(_this.props.pluginHooks.componentInteractions); 8134 var interactions = interactionClasses.map(function (TheInteractionClass) { return new TheInteractionClass(settings); }); 8135 _this.interactionsStore[component.uid] = interactions; 8136 interactionSettingsStore[component.uid] = settings; 8137 }; 8138 _this.unregisterInteractiveComponent = function (component) { 8139 var listeners = _this.interactionsStore[component.uid]; 8140 if (listeners) { 8141 for (var _i = 0, listeners_1 = listeners; _i < listeners_1.length; _i++) { 8142 var listener = listeners_1[_i]; 8143 listener.destroy(); 8144 } 8145 delete _this.interactionsStore[component.uid]; 8146 } 8147 delete interactionSettingsStore[component.uid]; 8148 }; 8149 // Resizing 8150 // ----------------------------------------------------------------------------------------------------------------- 8151 _this.resizeRunner = new DelayedRunner(function () { 8152 _this.props.emitter.trigger('_resize', true); // should window resizes be considered "forced" ? 8153 _this.props.emitter.trigger('windowResize', { view: _this.props.viewApi }); 8154 }); 8155 _this.handleWindowResize = function (ev) { 8156 var options = _this.props.options; 8157 if (options.handleWindowResize && 8158 ev.target === window // avoid jqui events 8159 ) { 8160 _this.resizeRunner.request(options.windowResizeDelay); 8161 } 8162 }; 8163 return _this; 8164 } 8165 /* 8166 renders INSIDE of an outer div 8167 */ 8168 CalendarContent.prototype.render = function () { 8169 var props = this.props; 8170 var toolbarConfig = props.toolbarConfig, options = props.options; 8171 var toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, getNow(props.options.now, props.dateEnv), // TODO: use NowTimer???? 8172 props.viewTitle); 8173 var viewVGrow = false; 8174 var viewHeight = ''; 8175 var viewAspectRatio; 8176 if (props.isHeightAuto || props.forPrint) { 8177 viewHeight = ''; 8178 } 8179 else if (options.height != null) { 8180 viewVGrow = true; 8181 } 8182 else if (options.contentHeight != null) { 8183 viewHeight = options.contentHeight; 8184 } 8185 else { 8186 viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall 8187 } 8188 var viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent); 8189 var viewLabelId = (toolbarConfig.header && toolbarConfig.header.hasTitle) 8190 ? this.state.viewLabelId 8191 : ''; 8192 return (createElement(ViewContextType.Provider, { value: viewContext }, 8193 toolbarConfig.header && (createElement(Toolbar, __assign({ ref: this.headerRef, extraClassName: "fc-header-toolbar", model: toolbarConfig.header, titleId: viewLabelId }, toolbarProps))), 8194 createElement(ViewContainer, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, labeledById: viewLabelId }, 8195 this.renderView(props), 8196 this.buildAppendContent()), 8197 toolbarConfig.footer && (createElement(Toolbar, __assign({ ref: this.footerRef, extraClassName: "fc-footer-toolbar", model: toolbarConfig.footer, titleId: "" }, toolbarProps))))); 8198 }; 8199 CalendarContent.prototype.componentDidMount = function () { 8200 var props = this.props; 8201 this.calendarInteractions = props.pluginHooks.calendarInteractions 8202 .map(function (CalendarInteractionClass) { return new CalendarInteractionClass(props); }); 8203 window.addEventListener('resize', this.handleWindowResize); 8204 var propSetHandlers = props.pluginHooks.propSetHandlers; 8205 for (var propName in propSetHandlers) { 8206 propSetHandlers[propName](props[propName], props); 8207 } 8208 }; 8209 CalendarContent.prototype.componentDidUpdate = function (prevProps) { 8210 var props = this.props; 8211 var propSetHandlers = props.pluginHooks.propSetHandlers; 8212 for (var propName in propSetHandlers) { 8213 if (props[propName] !== prevProps[propName]) { 8214 propSetHandlers[propName](props[propName], props); 8215 } 8216 } 8217 }; 8218 CalendarContent.prototype.componentWillUnmount = function () { 8219 window.removeEventListener('resize', this.handleWindowResize); 8220 this.resizeRunner.clear(); 8221 for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) { 8222 var interaction = _a[_i]; 8223 interaction.destroy(); 8224 } 8225 this.props.emitter.trigger('_unmount'); 8226 }; 8227 CalendarContent.prototype.buildAppendContent = function () { 8228 var props = this.props; 8229 var children = props.pluginHooks.viewContainerAppends.map(function (buildAppendContent) { return buildAppendContent(props); }); 8230 return createElement.apply(void 0, __spreadArray([Fragment, {}], children)); 8231 }; 8232 CalendarContent.prototype.renderView = function (props) { 8233 var pluginHooks = props.pluginHooks; 8234 var viewSpec = props.viewSpec; 8235 var viewProps = { 8236 dateProfile: props.dateProfile, 8237 businessHours: props.businessHours, 8238 eventStore: props.renderableEventStore, 8239 eventUiBases: props.eventUiBases, 8240 dateSelection: props.dateSelection, 8241 eventSelection: props.eventSelection, 8242 eventDrag: props.eventDrag, 8243 eventResize: props.eventResize, 8244 isHeightAuto: props.isHeightAuto, 8245 forPrint: props.forPrint, 8246 }; 8247 var transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers); 8248 for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) { 8249 var transformer = transformers_1[_i]; 8250 __assign(viewProps, transformer.transform(viewProps, props)); 8251 } 8252 var ViewComponent = viewSpec.component; 8253 return (createElement(ViewComponent, __assign({}, viewProps))); 8254 }; 8255 return CalendarContent; 8256 }(PureComponent)); 8257 function buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) { 8258 // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid 8259 var todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason 8260 var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false); 8261 var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false); 8262 return { 8263 title: title, 8264 activeButton: viewSpec.type, 8265 navUnit: viewSpec.singleUnit, 8266 isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now), 8267 isPrevEnabled: prevInfo.isValid, 8268 isNextEnabled: nextInfo.isValid, 8269 }; 8270 } 8271 // Plugin 8272 // ----------------------------------------------------------------------------------------------------------------- 8273 function buildViewPropTransformers(theClasses) { 8274 return theClasses.map(function (TheClass) { return new TheClass(); }); 8275 } 8276 8277 var CalendarRoot = /** @class */ (function (_super) { 8278 __extends(CalendarRoot, _super); 8279 function CalendarRoot() { 8280 var _this = _super !== null && _super.apply(this, arguments) || this; 8281 _this.state = { 8282 forPrint: false, 8283 }; 8284 _this.handleBeforePrint = function () { 8285 _this.setState({ forPrint: true });
8286 }; 8287 _this.handleAfterPrint = function () { 8288 _this.setState({ forPrint: false }); 8289 }; 8290 return _this; 8291 } 8292 CalendarRoot.prototype.render = function () { 8293 var props = this.props; 8294 var options = props.options; 8295 var forPrint = this.state.forPrint; 8296 var isHeightAuto = forPrint || options.height === 'auto' || options.contentHeight === 'auto'; 8297 var height = (!isHeightAuto && options.height != null) ? options.height : ''; 8298 var classNames = [ 8299 'fc', 8300 forPrint ? 'fc-media-print' : 'fc-media-screen', 8301 "fc-direction-" + options.direction, 8302 props.theme.getClass('root'), 8303 ]; 8304 if (!getCanVGrowWithinCell()) { 8305 classNames.push('fc-liquid-hack'); 8306 } 8307 return props.children(classNames, height, isHeightAuto, forPrint); 8308 }; 8309 CalendarRoot.prototype.componentDidMount = function () { 8310 var emitter = this.props.emitter; 8311 emitter.on('_beforeprint', this.handleBeforePrint); 8312 emitter.on('_afterprint', this.handleAfterPrint); 8313 }; 8314 CalendarRoot.prototype.componentWillUnmount = function () { 8315 var emitter = this.props.emitter; 8316 emitter.off('_beforeprint', this.handleBeforePrint); 8317 emitter.off('_afterprint', this.handleAfterPrint); 8318 }; 8319 return CalendarRoot; 8320 }(BaseComponent)); 8321 8322 // Computes a default column header formatting string if `colFormat` is not explicitly defined 8323 function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) { 8324 // if more than one week row, or if there are a lot of columns with not much space, 8325 // put just the day numbers will be in each cell 8326 if (!datesRepDistinctDays || dayCnt > 10) { 8327 return createFormatter({ weekday: 'short' }); // "Sat" 8328 } 8329 if (dayCnt > 1) { 8330 return createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }); // "Sat 11/12" 8331 } 8332 return createFormatter({ weekday: 'long' }); // "Saturday" 8333 } 8334 8335 var CLASS_NAME = 'fc-col-header-cell'; // do the cushion too? no 8336 function renderInner$1(hookProps) { 8337 return hookProps.text; 8338 } 8339 8340 var TableDateCell = /** @class */ (function (_super) { 8341 __extends(TableDateCell, _super); 8342 function TableDateCell() { 8343 return _super !== null && _super.apply(this, arguments) || this; 8344 } 8345 TableDateCell.prototype.render = function () { 8346 var _a = this.context, dateEnv = _a.dateEnv, options = _a.options, theme = _a.theme, viewApi = _a.viewApi; 8347 var props = this.props; 8348 var date = props.date, dateProfile = props.dateProfile; 8349 var dayMeta = getDateMeta(date, props.todayRange, null, dateProfile); 8350 var classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme)); 8351 var text = dateEnv.format(date, props.dayHeaderFormat); 8352 // if colCnt is 1, we are already in a day-view and don't need a navlink 8353 var navLinkAttrs = (!dayMeta.isDisabled && props.colCnt > 1) 8354 ? buildNavLinkAttrs(this.context, date) 8355 : {}; 8356 var hookProps = __assign(__assign(__assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraHookProps), { text: text }), dayMeta); 8357 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner$1, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("th", __assign({ ref: rootElRef, role: "columnheader", className: classNames.concat(customClassNames).join(' '), "data-date": !dayMeta.isDisabled ? formatDayString(date) : undefined, colSpan: props.colSpan }, props.extraDataAttrs), 8358 createElement("div", { className: "fc-scrollgrid-sync-inner" }, !dayMeta.isDisabled && (createElement("a", __assign({ ref: innerElRef, className: [ 8359 'fc-col-header-cell-cushion', 8360 props.isSticky ? 'fc-sticky' : '', 8361 ].join(' ') }, navLinkAttrs), innerContent))))); })); 8362 }; 8363 return TableDateCell; 8364 }(BaseComponent)); 8365 8366 var WEEKDAY_FORMAT = createFormatter({ weekday: 'long' }); 8367 var TableDowCell = /** @class */ (function (_super) { 8368 __extends(TableDowCell, _super); 8369 function TableDowCell() { 8370 return _super !== null && _super.apply(this, arguments) || this; 8371 } 8372 TableDowCell.prototype.render = function () { 8373 var props = this.props; 8374 var _a = this.context, dateEnv = _a.dateEnv, theme = _a.theme, viewApi = _a.viewApi, options = _a.options; 8375 var date = addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT 8376 var dateMeta = { 8377 dow: props.dow, 8378 isDisabled: false, 8379 isFuture: false, 8380 isPast: false, 8381 isToday: false, 8382 isOther: false, 8383 }; 8384 var classNames = [CLASS_NAME].concat(getDayClassNames(dateMeta, theme), props.extraClassNames || []); 8385 var text = dateEnv.format(date, props.dayHeaderFormat); 8386 var hookProps = __assign(__assign(__assign(__assign({ // TODO: make this public? 8387 date: date }, dateMeta), { view: viewApi }), props.extraHookProps), { text: text }); 8388 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner$1, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("th", __assign({ ref: rootElRef, role: "columnheader", className: classNames.c
8388oncat(customClassNames).join(' '), colSpan: props.colSpan }, props.extraDataAttrs), 8389 createElement("div", { className: "fc-scrollgrid-sync-inner" }, 8390 createElement("a", { "aria-label": dateEnv.format(date, WEEKDAY_FORMAT), className: [ 8391 'fc-col-header-cell-cushion', 8392 props.isSticky ? 'fc-sticky' : '', 8393 ].join(' '), ref: innerElRef }, innerContent)))); })); 8394 }; 8395 return TableDowCell; 8396 }(BaseComponent)); 8397 8398 var NowTimer = /** @class */ (function (_super) { 8399 __extends(NowTimer, _super); 8400 function NowTimer(props, context) { 8401 var _this = _super.call(this, props, context) || this; 8402 _this.initialNowDate = getNow(context.options.now, context.dateEnv); 8403 _this.initialNowQueriedMs = new Date().valueOf(); 8404 _this.state = _this.computeTiming().currentState; 8405 return _this; 8406 } 8407 NowTimer.prototype.render = function () { 8408 var _a = this, props = _a.props, state = _a.state; 8409 return props.children(state.nowDate, state.todayRange); 8410 }; 8411 NowTimer.prototype.componentDidMount = function () { 8412 this.setTimeout(); 8413 }; 8414 NowTimer.prototype.componentDidUpdate = function (prevProps) { 8415 if (prevProps.unit !== this.props.unit) { 8416 this.clearTimeout(); 8417 this.setTimeout(); 8418 } 8419 }; 8420 NowTimer.prototype.componentWillUnmount = function () { 8421 this.clearTimeout(); 8422 }; 8423 NowTimer.prototype.computeTiming = function () { 8424 var _a = this, props = _a.props, context = _a.context; 8425 var unroundedNow = addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs); 8426 var currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit); 8427 var nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit)); 8428 var waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf(); 8429 // there is a max setTimeout ms value (https://stackoverflow.com/a/3468650/96342) 8430 // ensure no longer than a day 8431 waitMs = Math.min(1000 * 60 * 60 * 24, waitMs); 8432 return { 8433 currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) }, 8434 nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) }, 8435 waitMs: waitMs, 8436 }; 8437 }; 8438 NowTimer.prototype.setTimeout = function () { 8439 var _this = this; 8440 var _a = this.computeTiming(), nextState = _a.nextState, waitMs = _a.waitMs; 8441 this.timeoutId = setTimeout(function () { 8442 _this.setState(nextState, function () { 8443 _this.setTimeout(); 8444 }); 8445 }, waitMs); 8446 }; 8447 NowTimer.prototype.clearTimeout = function () { 8448 if (this.timeoutId) { 8449 clearTimeout(this.timeoutId); 8450 } 8451 }; 8452 NowTimer.contextType = ViewContextType; 8453 return NowTimer; 8454 }(Component)); 8455 function buildDayRange(date) { 8456 var start = startOfDay(date); 8457 var end = addDays(start, 1); 8458 return { start: start, end: end }; 8459 } 8460 8461 var DayHeader = /** @class */ (function (_super) { 8462 __extends(DayHeader, _super); 8463 function DayHeader() { 8464 var _this = _super !== null && _super.apply(this, arguments) || this; 8465 _this.createDayHeaderFormatter = memoize(createDayHeaderFormatter); 8466 return _this; 8467 } 8468 DayHeader.prototype.render = function () { 8469 var context = this.context; 8470 var _a = this.props, dates = _a.dates, dateProfile = _a.dateProfile, datesRepDistinctDays = _a.datesRepDistinctDays, renderIntro = _a.renderIntro; 8471 var dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length); 8472 return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement("tr", { role: "row" }, 8473 renderIntro && renderIntro('day'), 8474 dates.map(function (date) { return (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 }))); }))); })); 8475 }; 8476 return DayHeader; 8477 }(BaseComponent)); 8478 function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) { 8479 return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt); 8480 } 8481
8482 var DaySeriesModel = /** @class */ (function () { 8483 function DaySeriesModel(range, dateProfileGenerator) { 8484 var date = range.start; 8485 var end = range.end; 8486 var indices = []; 8487 var dates = []; 8488 var dayIndex = -1; 8489 while (date < end) { // loop each day from start to end 8490 if (dateProfileGenerator.isHiddenDay(date)) { 8491 indices.push(dayIndex + 0.5); // mark that it's between indices 8492 } 8493 else { 8494 dayIndex += 1; 8495 indices.push(dayIndex); 8496 dates.push(date); 8497 } 8498 date = addDays(date, 1); 8499 } 8500 this.dates = dates; 8501 this.indices = indices; 8502 this.cnt = dates.length; 8503 } 8504 DaySeriesModel.prototype.sliceRange = function (range) { 8505 var firstIndex = this.getDateDayIndex(range.start); // inclusive first index 8506 var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index 8507 var clippedFirstIndex = Math.max(0, firstIndex); 8508 var clippedLastIndex = Math.min(this.cnt - 1, lastIndex); 8509 // deal with in-between indices 8510 clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell 8511 clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell 8512 if (clippedFirstIndex <= clippedLastIndex) { 8513 return { 8514 firstIndex: clippedFirstIndex, 8515 lastIndex: clippedLastIndex, 8516 isStart: firstIndex === clippedFirstIndex, 8517 isEnd: lastIndex === clippedLastIndex, 8518 }; 8519 } 8520 return null; 8521 }; 8522 // Given a date, returns its chronolocial cell-index from the first cell of the grid. 8523 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets. 8524 // If before the first offset, returns a negative number. 8525 // If after the last offset, returns an offset past the last cell offset. 8526 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells. 8527 DaySeriesModel.prototype.getDateDayIndex = function (date) { 8528 var indices = this.indices; 8529 var dayOffset = Math.floor(diffDays(this.dates[0], date)); 8530 if (dayOffset < 0) { 8531 return indices[0] - 1; 8532 } 8533 if (dayOffset >= indices.length) { 8534 return indices[indices.length - 1] + 1; 8535 } 8536 return indices[dayOffset]; 8537 };
8538 return DaySeriesModel; 8539 }()); 8540 8541 var DayTableModel = /** @class */ (function () { 8542 function DayTableModel(daySeries, breakOnWeeks) { 8543 var dates = daySeries.dates; 8544 var daysPerRow; 8545 var firstDay; 8546 var rowCnt; 8547 if (breakOnWeeks) { 8548 // count columns until the day-of-week repeats 8549 firstDay = dates[0].getUTCDay(); 8550 for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow += 1) { 8551 if (dates[daysPerRow].getUTCDay() === firstDay) { 8552 break; 8553 } 8554 } 8555 rowCnt = Math.ceil(dates.length / daysPerRow); 8556 } 8557 else { 8558 rowCnt = 1; 8559 daysPerRow = dates.length; 8560 } 8561 this.rowCnt = rowCnt; 8562 this.colCnt = daysPerRow; 8563 this.daySeries = daySeries; 8564 this.cells = this.buildCells(); 8565 this.headerDates = this.buildHeaderDates(); 8566 } 8567 DayTableModel.prototype.buildCells = function () { 8568 var rows = []; 8569 for (var row = 0; row < this.rowCnt; row += 1) { 8570 var cells = []; 8571 for (var col = 0; col < this.colCnt; col += 1) { 8572 cells.push(this.buildCell(row, col)); 8573 } 8574 rows.push(cells); 8575 } 8576 return rows; 8577 }; 8578 DayTableModel.prototype.buildCell = function (row, col) { 8579 var date = this.daySeries.dates[row * this.colCnt + col]; 8580 return { 8581 key: date.toISOString(), 8582 date: date, 8583 }; 8584 }; 8585 DayTableModel.prototype.buildHeaderDates = function () { 8586 var dates = []; 8587 for (var col = 0; col < this.colCnt; col += 1) { 8588 dates.push(this.cells[0][col].date); 8589 } 8590 return dates; 8591 }; 8592 DayTableModel.prototype.sliceRange = function (range) { 8593 var colCnt = this.colCnt; 8594 var seriesSeg = this.daySeries.sliceRange(range); 8595 var segs = []; 8596 if (seriesSeg) { 8597 var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex; 8598 var index = firstIndex; 8599 while (index <= lastIndex) { 8600 var row = Math.floor(index / colCnt); 8601 var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1); 8602 segs.push({ 8603 row: row, 8604 firstCol: index % colCnt, 8605 lastCol: (nextIndex - 1) % colCnt, 8606 isStart: seriesSeg.isStart && index === firstIndex, 8607 isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex, 8608 }); 8609 index = nextIndex; 8610 } 8611 } 8612 return segs; 8613 }; 8614 return DayTableModel; 8615 }()); 8616 8617 var Slicer = /** @class */ (function () { 8618 function Slicer() { 8619 this.sliceBusinessHours = memoize(this._sliceBusinessHours); 8620 this.sliceDateSelection = memoize(this._sliceDateSpan); 8621 this.sliceEventStore = memoize(this._sliceEventStore); 8622 this.sliceEventDrag = memoize(this._sliceInteraction); 8623 this.sliceEventResize = memoize(this._sliceInteraction); 8624 this.forceDayIfListItem = false; // hack 8625 } 8626 Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, context) { 8627 var extraArgs = []; 8628 for (var _i = 4; _i < arguments.length; _i++) { 8629 extraArgs[_i - 4] = arguments[_i]; 8630 } 8631 var eventUiBases = props.eventUiBases; 8632 var eventSegs = this.sliceEventStore.apply(this, __spreadArray([props.eventStore, eventUiBases, dateProfile, nextDayThreshold], extraArgs)); 8633 return { 8634 dateSelectionSegs: this.sliceDateSelection.apply(this, __spreadArray([props.dateSelection, eventUiBases, context], extraArgs)), 8635 businessHourSegs: this.sliceBusinessHours.apply(this, __spreadArray([props.businessHours, dateProfile, nextDayThreshold, context], extraArgs)), 8636 fgEventSegs: eventSegs.fg, 8637 bgEventSegs: eventSegs.bg, 8638 eventDrag: this.sliceEventDrag.apply(this, __spreadArray([props.eventDrag, eventUiBases, dateProfile, nextDayThreshold], extraArgs)), 8639 eventResize: this.sliceEventResize.apply(this, __spreadArray([props.eventResize, eventUiBases, dateProfile, nextDayThreshold], extraArgs)), 8640 eventSelection: props.eventSelection, 8641 }; // TODO: give interactionSegs? 8642 }; 8643 Slicer.prototype.sliceNowDate = function (// does not memoize 8644 date, context) { 8645 var extraArgs = []; 8646 for (var _i = 2; _i < arguments.length; _i++) { 8647 extraArgs[_i - 2] = arguments[_i]; 8648 } 8649 return this._sliceDateSpan.apply(this, __spreadArray([{ range: { start: date, end: addMs(date, 1) }, allDay: false }, 8650 {}, 8651 context], extraArgs)); 8652 }; 8653 Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, context) { 8654 var extraArgs = []; 8655 for (var _i = 4; _i < arguments.length; _i++) { 8656 extraArgs[_i - 4] = arguments[_i]; 8657 } 8658 if (!businessHours) { 8659 return []; 8660 } 8661 return this._sliceEventStore.apply(this, __spreadArray([expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context), 8662 {}, 8663 dateProfile, 8664 nextDayThreshold], extraArgs)).bg; 8665 }; 8666 Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold) { 8667 var extraArgs = []; 8668 for (var _i = 4; _i < arguments.length; _i++) { 8669 extraArgs[_i - 4] = arguments[_i]; 8670 } 8671 if (eventStore) { 8672 var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 8673 return { 8674 bg: this.sliceEventRanges(rangeRes.bg, extraArgs), 8675 fg: this.sliceEventRanges(rangeRes.fg, extraArgs), 8676 }; 8677 } 8678 return { bg: [], fg: [] }; 8679 }; 8680 Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold) { 8681 var extraArgs = []; 8682 for (var _i = 4; _i < arguments.length; _i++) { 8683 extraArgs[_i - 4] = arguments[_i]; 8684 } 8685 if (!interaction) { 8686 return null; 8687 } 8688 var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 8689 return { 8690 segs: this.sliceEventRanges(rangeRes.fg, extraArgs), 8691 affectedInstances: interaction.affectedEvents.instances, 8692 isEvent: interaction.isEvent, 8693 }; 8694 }; 8695 Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, context) { 8696 var extraArgs = []; 8697 for (var _i = 3; _i < arguments.length; _i++) { 8698 extraArgs[_i - 3] = arguments[_i]; 8699 } 8700 if (!dateSpan) { 8701 return []; 8702 } 8703 var eventRange = fabricateEventRange(dateSpan, eventUiBases, context); 8704 var segs = this.sliceRange.apply(this, __spreadArray([dateSpan.range], extraArgs)); 8705 for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) { 8706 var seg = segs_1[_a]; 8707 seg.eventRange = eventRange; 8708 } 8709 return segs; 8710 }; 8711 /* 8712 "complete" seg means it has component and eventRange 8713 */ 8714 Slicer.prototype.sliceEventRanges = function (eventRanges, extraArgs) { 8715 var segs = []; 8716 for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) { 8717 var eventRange = eventRanges_1[_i]; 8718 segs.push.apply(segs, this.sliceEventRange(eventRange, extraArgs)); 8719 } 8720 return segs; 8721 }; 8722 /* 8723 "complete" seg means it has component and eventRange 8724 */ 8725 Slicer.prototype.sliceEventRange = function (eventRange, extraArgs) { 8726 var dateRange = eventRange.range; 8727 // hack to make multi-day events that are being force-displayed as list-items to take up only one day 8728 if (this.forceDayIfListItem && eventRange.ui.display === 'list-item') { 8729 dateRange = { 8730 start: dateRange.start, 8731 end: addDays(dateRange.start, 1), 8732 }; 8733 } 8734 var segs = this.sliceRange.apply(this, __spreadArray([dateRange], extraArgs)); 8735 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 8736 var seg = segs_2[_i]; 8737 seg.eventRange = eventRange; 8738 seg.isStart = eventRange.isStart && seg.isStart; 8739 seg.isEnd = eventRange.isEnd && seg.isEnd; 8740 } 8741 return segs; 8742 }; 8743 return Slicer; 8744 }()); 8745 /* 8746 for incorporating slotMinTime/slotMaxTime if appropriate 8747 TODO: should be part of DateProfile! 8748 TimelineDateProfile already does this btw 8749 */ 8750 function computeActiveRange(dateProfile, isComponentAllDay) { 8751 var range = dateProfile.activeRange; 8752 if (isComponentAllDay) { 8753 return range; 8754 } 8755 return { 8756 start: addMs(range.start, dateProfile.slotMinTime.milliseconds), 8757 end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5), // 864e5 = ms in a day 8758 }; 8759 } 8760 8761 // high-level segmenting-aware tester functions 8762 // ------------------------------------------------------------------------------------------------------------------------ 8763 function isInteractionValid(interaction, dateProfile, context) { 8764 var instances = interaction.mutatedEvents.instances; 8765 for (var instanceId in instances) { 8766 if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) { 8767 return false; 8768 } 8769 } 8770 return isNewPropsValid({ eventDrag: interaction }, context); // HACK: the eventDrag props is used for ALL interactions 8771 } 8772 function isDateSelectionValid(dateSelection, dateProfile, context) { 8773 if (!rangeContainsRange(dateProfile.validRange, dateSelection.range)) { 8774 return false; 8775 } 8776 return isNewPropsValid({ dateSelection: dateSelection }, context); 8777 } 8778 function isNewPropsValid(newProps, context) { 8779 var calendarState = context.getCurrentData(); 8780 var props = __assign({ businessHours: calendarState.businessHours, dateSelection: '', eventStore: calendarState.eventStore, eventUiBases: calendarState.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps); 8781 return (context.pluginHooks.isPropsValid || isPropsValid)(props, context); 8782 } 8783 function isPropsValid(state, context, dateSpanMeta, filterConfig) {
8784 if (dateSpanMeta === void 0) { dateSpanMeta = {}; } 8785 if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) { 8786 return false; 8787 } 8788 if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) { 8789 return false; 8790 } 8791 return true; 8792 } 8793 // Moving Event Validation 8794 // ------------------------------------------------------------------------------------------------------------------------ 8795 function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) { 8796 var currentState = context.getCurrentData(); 8797 var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions 8798 var subjectEventStore = interaction.mutatedEvents; 8799 var subjectDefs = subjectEventStore.defs; 8800 var subjectInstances = subjectEventStore.instances; 8801 var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ? 8802 state.eventUiBases : 8803 { '': currentState.selectionConfig }); 8804 if (filterConfig) { 8805 subjectConfigs = mapHash(subjectConfigs, filterConfig); 8806 } 8807 // exclude the subject events. TODO: exclude defs too? 8808 var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); 8809 var otherDefs = otherEventStore.defs; 8810 var otherInstances = otherEventStore.instances; 8811 var otherConfigs = compileEventUis(otherDefs, state.eventUiBases); 8812 for (var subjectInstanceId in subjectInstances) { 8813 var subjectInstance = subjectInstances[subjectInstanceId]; 8814 var subjectRange = subjectInstance.range; 8815 var subjectConfig = subjectConfigs[subjectInstance.defId]; 8816 var subjectDef = subjectDefs[subjectInstance.defId]; 8817 // constraint 8818 if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) { 8819 return false; 8820 } 8821 // overlap 8822 var eventOverlap = context.options.eventOverlap; 8823 var eventOverlapFunc = typeof eventOverlap === 'function' ? eventOverlap : null; 8824 for (var otherInstanceId in otherInstances) { 8825 var otherInstance = otherInstances[otherInstanceId]; 8826 // intersect! evaluate 8827 if (rangesIntersect(subjectRange, otherInstance.range)) { 8828 var otherOverlap = otherConfigs[otherInstance.defId].overlap; 8829 // consider the other event's overlap. only do this if the subject event is a "real" event 8830 if (otherOverlap === false && interaction.isEvent) { 8831 return false; 8832 } 8833 if (subjectConfig.overlap === false) { 8834 return false; 8835 } 8836 if (eventOverlapFunc && !eventOverlapFunc(new EventApi(context, otherDefs[otherInstance.defId], otherInstance), // still event 8837 new EventApi(context, subjectDef, subjectInstance))) { 8838 return false; 8839 } 8840 } 8841 } 8842 // allow (a function) 8843 var calendarEventStore = currentState.eventStore; // need global-to-calendar, not local to component (splittable)state 8844 for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) { 8845 var subjectAllow = _a[_i]; 8846 var subjectDateSpan = __assign(__assign({}, dateSpanMeta), { range: subjectInstance.range, allDay: subjectDef.allDay }); 8847 var origDef = calendarEventStore.defs[subjectDef.defId]; 8848 var origInstance = calendarEventStore.instances[subjectInstanceId]; 8849 var eventApi = void 0; 8850 if (origDef) { // was previously in the calendar 8851 eventApi = new EventApi(context, origDef, origInstance); 8852 } 8853 else { // was an external event 8854 eventApi = new EventApi(context, subjectDef); // no instance, because had no dates 8855 } 8856 if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) { 8857 return false; 8858 } 8859 } 8860 } 8861 return true; 8862 } 8863 // Date Selection Validation 8864 // ------------------------------------------------------------------------------------------------------------------------ 8865 function isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) { 8866 var relevantEventStore = state.eventStore; 8867 var relevantDefs = relevantEventStore.defs; 8868 var relevantInstances = relevantEventStore.instances; 8869 var selection = state.dateSelection; 8870 var selectionRange = selection.range; 8871 var selectionConfig = context.getCurrentData().selectionConfig; 8872 if (filterConfig) { 8873 selectionConfig = filterConfig(selectionConfig); 8874 } 8875 // constraint 8876 if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) { 8877 return false; 8878 } 8879 // overlap 8880 var selectOverlap = context.options.selectOverlap; 8881 var selectOverlapFunc = typeof selectOverlap === 'function' ? selectOverlap : null; 8882 for (var relevantInstanceId in relevantInstances) { 8883 var relevantInstance = relevantInstances[relevantInstanceId]; 8884 // intersect! evaluate 8885 if (rangesIntersect(selectionRange, relevantInstance.range)) { 8886 if (selectionConfig.overlap === false) { 8887 return false; 8888 } 8889 if (selectOverlapFunc && !selectOverlapFunc(new EventApi(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) { 8890 return false; 8891 } 8892 } 8893 } 8894 // allow (a function) 8895 for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) { 8896 var selectionAllow = _a[_i]; 8897 var fullDateSpan = __assign(__assign({}, dateSpanMeta), selection); 8898 if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) { 8899 return false; 8900 } 8901 } 8902 return true; 8903 } 8904 // Constraint Utils 8905 // ------------------------------------------------------------------------------------------------------------------------ 8906 function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) { 8907 for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) { 8908 var constraint = constraints_1[_i]; 8909 if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) { 8910 return false; 8911 } 8912 } 8913 return true; 8914 } 8915 function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours 8916 otherEventStore, // for if constraint is an even group ID 8917 businessHoursUnexpanded, // for if constraint is 'businessHours' 8918 context) { 8919 if (constraint === 'businessHours') { 8920 return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context)); 8921 } 8922 if (typeof constraint === 'string') { // an group ID 8923 return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) { return eventDef.groupId === constraint; })); 8924 } 8925 if (typeof constraint === 'object' && constraint) { // non-null object 8926 return eventStoreToRanges(expandRecurring(constraint, subjectRange, context)); 8927 } 8928 return []; // if it's false 8929 } 8930 // TODO: move to event-store file? 8931 function eventStoreToRanges(eventStore) { 8932 var instances = eventStore.instances; 8933 var ranges = []; 8934 for (var instanceId in instances) { 8935 ranges.push(instances[instanceId].range); 8936 } 8937 return ranges; 8938 } 8939 // TODO: move to geom file? 8940 function anyRangesContainRange(outerRanges, innerRange) { 8941 for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) { 8942 var outerRange = outerRanges_1[_i]; 8943 if (rangeContainsRange(outerRange, innerRange)) { 8944 return true; 8945 } 8946 } 8947 return false; 8948 } 8949 8950 var VISIBLE_HIDDEN_RE = /^(visible|hidden)$/; 8951 var Scroller = /** @class */ (function (_super) { 8952 __extends(Scroller, _super); 8953 function Scroller() { 8954 var _this = _super !== null && _super.apply(this, arguments) || this; 8955 _this.handleEl = function (el) { 8956 _this.el = el; 8957 setRef(_this.props.elRef, el); 8958 }; 8959 return _this; 8960 } 8961 Scroller.prototype.render = function () { 8962 var props = this.props; 8963 var liquid = props.liquid, liquidIsAbsolute = props.liquidIsAbsolute; 8964 var isAbsolute = liquid && liquidIsAbsolute; 8965 var className = ['fc-scroller']; 8966 if (liquid) { 8967 if (liquidIsAbsolute) { 8968 className.push('fc-scroller-liquid-absolute'); 8969 } 8970 else { 8971 className.push('fc-scroller-liquid'); 8972 } 8973 } 8974 return (createElement("div", { ref: this.handleEl, className: className.join(' '), style: { 8975 overflowX: props.overflowX, 8976 overflowY: props.overflowY, 8977 left: (isAbsolute && -(props.overcomeLeft || 0)) || '', 8978 right: (isAbsolute && -(props.overcomeRight || 0
8978)) || '', 8979 bottom: (isAbsolute && -(props.overcomeBottom || 0)) || '', 8980 marginLeft: (!isAbsolute && -(props.overcomeLeft || 0)) || '', 8981 marginRight: (!isAbsolute && -(props.overcomeRight || 0)) || '', 8982 marginBottom: (!isAbsolute && -(props.overcomeBottom || 0)) || '', 8983 maxHeight: props.maxHeight || '', 8984 } }, props.children)); 8985 }; 8986 Scroller.prototype.needsXScrolling = function () { 8987 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 8988 return false; 8989 } 8990 // testing scrollWidth>clientWidth is unreliable cross-browser when pixel heights aren't integers. 8991 // much more reliable to see if children are taller than the scroller, even tho doesn't account for 8992 // inner-child margins and absolute positioning 8993 var el = this.el; 8994 var realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth(); 8995 var children = el.children; 8996 for (var i = 0; i < children.length; i += 1) { 8997 var childEl = children[i]; 8998 if (childEl.getBoundingClientRect().width > realClientWidth) { 8999 return true; 9000 } 9001 } 9002 return false; 9003 }; 9004 Scroller.prototype.needsYScrolling = function () { 9005 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 9006 return false; 9007 } 9008 // testing scrollHeight>clientHeight is unreliable cross-browser when pixel heights aren't integers. 9009 // much more reliable to see if children are taller than the scroller, even tho doesn't account for 9010 // inner-child margins and absolute positioning 9011 var el = this.el; 9012 var realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth(); 9013 var children = el.children; 9014 for (var i = 0; i < children.length; i += 1) { 9015 var childEl = children[i]; 9016 if (childEl.getBoundingClientRect().height > realClientHeight) { 9017 return true; 9018 } 9019 } 9020 return false; 9021 }; 9022 Scroller.prototype.getXScrollbarWidth = function () { 9023 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 9024 return 0; 9025 } 9026 return this.el.offsetHeight - this.el.clientHeight; // only works because we guarantee no borders. TODO: add to CSS with important? 9027 }; 9028 Scroller.prototype.getYScrollbarWidth = function () { 9029 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 9030 return 0; 9031 } 9032 return this.el.offsetWidth - this.el.clientWidth; // only works because we guarantee no borders. TODO: add to CSS with important? 9033 }; 9034 return Scroller; 9035 }(BaseComponent)); 9036 9037 /* 9038 TODO: somehow infer OtherArgs from masterCallback? 9039 TODO: infer RefType from masterCallback if provided 9040 */ 9041 var RefMap = /** @class */ (function () { 9042 function RefMap(masterCallback) { 9043 var _this = this; 9044 this.masterCallback = masterCallback; 9045 this.currentMap = {}; 9046 this.depths = {}; 9047 this.callbackMap = {}; 9048 this.handleValue = function (val, key) { 9049 var _a = _this, depths = _a.depths, currentMap = _a.currentMap; 9050 var removed = false; 9051 var added = false; 9052 if (val !== null) { 9053 // for bug... ACTUALLY: can probably do away with this now that callers don't share numeric indices anymore 9054 removed = (key in currentMap); 9055 currentMap[key] = val; 9056 depths[key] = (depths[key] || 0) + 1; 9057 added = true; 9058 } 9059 else { 9060 depths[key] -= 1; 9061 if (!depths[key]) { 9062 delete currentMap[key]; 9063 delete _this.callbackMap[key]; 9064 removed = true; 9065 } 9066 } 9067 if (_this.masterCallback) { 9068 if (removed) { 9069 _this.masterCallback(null, String(key)); 9070 } 9071 if (added) { 9072 _this.masterCallback(val, String(key)); 9073 } 9074 } 9075 }; 9076 } 9077 RefMap.prototype.createRef = function (key) { 9078 var _this = this; 9079 var refCallback = this.callbackMap[key]; 9080 if (!refCallback) { 9081 refCallback = this.callbackMap[key] = function (val) { 9082 _this.handleValue(val, String(key)); 9083 }; 9084 } 9085 return refCallback; 9086 }; 9087 // TODO: check callers that don't care about order. should use getAll instead 9088 // NOTE: this method has become less valuable now that we are encouraged to map order by some other index 9089 // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and "collect" 9090 RefMap.prototype.collect = function (startIndex, endIndex, step) { 9091 return collectFromHash(this.currentMap, startIndex, endIndex, step); 9092 }; 9093 RefMap.prototype.getAll = function () { 9094 return hashValuesToArray(this.currentMap); 9095 }; 9096 return RefMap; 9097 }()); 9098 9099 function computeShrinkWidth(chunkEls) { 9100 var shrinkCells = findElements(chunkEls, '.fc-scrollgrid-shrink'); 9101 var largestWidth = 0; 9102 for (var _i = 0, shrinkCells_1 = shrinkCells; _i < shrinkCells_1.length; _i++) { 9103 var shrinkCell = shrinkCells_1[_i]; 9104 largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell)); 9105 } 9106 return Math.ceil(largestWidth); // <table> elements work best with integers. round up to ensure contents fits 9107 } 9108 function getSectionHasLiquidHeight(props, sectionConfig) { 9109 return props.liquid && sectionConfig.liquid; // does the section do liquid-height? (need to have whole scrollgrid liquid-height as well) 9110 } 9111 function getAllowYScrolling(props, sectionConfig) { 9112 return sectionConfig.maxHeight != null || // if its possible for the height to max out, we might need scrollbars 9113 getSectionHasLiquidHeight(props, sectionConfig); // if the section is liquid height, it might condense enough to require scrollbars 9114 } 9115 // TODO: ONLY use `arg`. force out internal function to use same API 9116 function renderChunkContent(sectionConfig, chunkConfig, arg, isHeader) { 9117 var expandRows = arg.expandRows; 9118 var content = typeof chunkConfig.content === 'function' ? 9119 chunkConfig.content(arg) : 9120 createElement('table', { 9121 role: 'presentation', 9122 className: [ 9123 chunkConfig.tableClassName, 9124 sectionConfig.syncRowHeights ? 'fc-scrollgrid-sync-table' : '', 9125 ].join(' '), 9126 style: { 9127 minWidth: arg.tableMinWidth, 9128 width: arg.clientWidth, 9129 height: expandRows ? arg.clientHeight : '', // css `height` on a <table> serves as a min-height 9130 }, 9131 }, arg.tableColGroupNode, createElement(isHeader ? 'thead' : 'tbody', { 9132 role: 'presentation', 9133 }, typeof chunkConfig.rowContent === 'function' 9134 ? chunkConfig.rowContent(arg) 9135 : chunkConfig.rowContent)); 9136 return content; 9137 } 9138 function isColPropsEqual(cols0, cols1) { 9139 return isArraysEqual(cols0, cols1, isPropsEqual); 9140 } 9141 function renderMicroColGroup(cols, shrinkWidth) { 9142 var colNodes = []; 9143 /* 9144 for ColProps with spans, it would have been great to make a single <col span=""> 9145 HOWEVER, Chrome was getting messing up distributing the width to <td>/<th> elements with colspans. 9146 SOLUTION: making individual <col> elements makes Chrome behave. 9147 */ 9148 for (var _i = 0, cols_1 = cols; _i < cols_1.length; _i++) { 9149 var colProps = cols_1[_i]; 9150 var span = colProps.span || 1; 9151 for (var i = 0; i < span; i += 1) {
9152 colNodes.push(createElement("col", { style: { 9153 width: colProps.width === 'shrink' ? sanitizeShrinkWidth(shrinkWidth) : (colProps.width || ''), 9154 minWidth: colProps.minWidth || '', 9155 } })); 9156 } 9157 } 9158 return createElement.apply(void 0, __spreadArray(['colgroup', {}], colNodes)); 9159 } 9160 function sanitizeShrinkWidth(shrinkWidth) { 9161 /* why 4? if we do 0, it will kill any border, which are needed for computeSmallestCellWidth 9162 4 accounts for 2 2-pixel borders. TODO: better solution? */ 9163 return shrinkWidth == null ? 4 : shrinkWidth; 9164 } 9165 function hasShrinkWidth(cols) { 9166 for (var _i = 0, cols_2 = cols; _i < cols_2.length; _i++) { 9167 var col = cols_2[_i]; 9168 if (col.width === 'shrink') { 9169 return true; 9170 } 9171 } 9172 return false; 9173 } 9174 function getScrollGridClassNames(liquid, context) { 9175 var classNames = [ 9176 'fc-scrollgrid', 9177 context.theme.getClass('table'), 9178 ]; 9179 if (liquid) { 9180 classNames.push('fc-scrollgrid-liquid'); 9181 } 9182 return classNames; 9183 } 9184 function getSectionClassNames(sectionConfig, wholeTableVGrow) { 9185 var classNames = [ 9186 'fc-scrollgrid-section', 9187 "fc-scrollgrid-section-" + sectionConfig.type, 9188 sectionConfig.className, // used? 9189 ]; 9190 if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) { 9191 classNames.push('fc-scrollgrid-section-liquid'); 9192 } 9193 if (sectionConfig.isSticky) { 9194 classNames.push('fc-scrollgrid-section-sticky'); 9195 } 9196 return classNames; 9197 }
9198 function renderScrollShim(arg) { 9199 return (createElement("div", { className: "fc-scrollgrid-sticky-shim", style: { 9200 width: arg.clientWidth, 9201 minWidth: arg.tableMinWidth, 9202 } })); 9203 } 9204 function getStickyHeaderDates(options) { 9205 var stickyHeaderDates = options.stickyHeaderDates; 9206 if (stickyHeaderDates == null || stickyHeaderDates === 'auto') { 9207 stickyHeaderDates = options.height === 'auto' || options.viewHeight === 'auto'; 9208 } 9209 return stickyHeaderDates; 9210 } 9211 function getStickyFooterScrollbar(options) { 9212 var stickyFooterScrollbar = options.stickyFooterScrollbar; 9213 if (stickyFooterScrollbar == null || stickyFooterScrollbar === 'auto') { 9214 stickyFooterScrollbar = options.height === 'auto' || options.viewHeight === 'auto'; 9215 } 9216 return stickyFooterScrollbar; 9217 } 9218 9219 var SimpleScrollGrid = /** @class */ (function (_super) { 9220 __extends(SimpleScrollGrid, _super); 9221 function SimpleScrollGrid() { 9222 var _this = _super !== null && _super.apply(this, arguments) || this; 9223 _this.processCols = memoize(function (a) { return a; }, isColPropsEqual); // so we get same `cols` props every time 9224 // yucky to memoize VNodes, but much more efficient for consumers 9225 _this.renderMicroColGroup = memoize(renderMicroColGroup); 9226 _this.scrollerRefs = new RefMap(); 9227 _this.scrollerElRefs = new RefMap(_this._handleScrollerEl.bind(_this)); 9228 _this.state = { 9229 shrinkWidth: null, 9230 forceYScrollbars: false, 9231 scrollerClientWidths: {}, 9232 scrollerClientHeights: {}, 9233 }; 9234 // TODO: can do a really simple print-view. dont need to join rows 9235 _this.handleSizing = function () { 9236 _this.setState(__assign({ shrinkWidth: _this.computeShrinkWidth() }, _this.computeScrollerDims())); 9237 }; 9238 return _this; 9239 } 9240 SimpleScrollGrid.prototype.render = function () { 9241 var _a = this, props = _a.props, state = _a.state, context = _a.context; 9242 var sectionConfigs = props.sections || []; 9243 var cols = this.processCols(props.cols); 9244 var microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth); 9245 var classNames = getScrollGridClassNames(props.liquid, context); 9246 if (props.collapsibleWidth) { 9247 classNames.push('fc-scrollgrid-collapsible'); 9248 } 9249 // TODO: make DRY 9250 var configCnt = sectionConfigs.length; 9251 var configI = 0; 9252 var currentConfig; 9253 var headSectionNodes = []; 9254 var bodySectionNodes = []; 9255 var footSectionNodes = []; 9256 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') { 9257 headSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true)); 9258 configI += 1; 9259 } 9260 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'body') { 9261 bodySectionNodes.push(this.renderSection(currentConfig, microColGroupNode, false)); 9262 configI += 1; 9263 } 9264 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'footer') { 9265 footSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true)); 9266 configI += 1; 9267 } 9268 // firefox bug: when setting height on table and there is a thead or tfoot, 9269 // the necessary height:100% on the liquid-height body section forces the *whole* table to be taller. (bug #5524) 9270 // use getCanVGrowWithinCell as a way to detect table-stupid firefox. 9271 // if so, use a simpler dom structure, jam everything into a lone tbody. 9272 var isBuggy = !getCanVGrowWithinCell(); 9273 var roleAttrs = { role: 'rowgroup' }; 9274 return createElement('table', { 9275 role: 'grid', 9276 className: classNames.join(' '), 9277 style: { height: props.height }, 9278 }, Boolean(!isBuggy && headSectionNodes.length) && createElement.apply(void 0, __spreadArray(['thead', roleAttrs], headSectionNodes
9278)), Boolean(!isBuggy && bodySectionNodes.length) && createElement.apply(void 0, __spreadArray(['tbody', roleAttrs], bodySectionNodes)), Boolean(!isBuggy && footSectionNodes.length) && createElement.apply(void 0, __spreadArray(['tfoot', roleAttrs], footSectionNodes)), isBuggy && createElement.apply(void 0, __spreadArray(__spreadArray(__spreadArray(['tbody', roleAttrs], headSectionNodes), bodySectionNodes), footSectionNodes))); 9279 }; 9280 SimpleScrollGrid.prototype.renderSection = function (sectionConfig, microColGroupNode, isHeader) { 9281 if ('outerContent' in sectionConfig) { 9282 return (createElement(Fragment, { key: sectionConfig.key }, sectionConfig.outerContent)); 9283 } 9284 return (createElement("tr", { key: sectionConfig.key, role: "presentation", className: getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, this.renderChunkTd(sectionConfig, microColGroupNode, sectionConfig.chunk, isHeader))); 9285 }; 9286 SimpleScrollGrid.prototype.renderChunkTd = function (sectionConfig, microColGroupNode, chunkConfig, isHeader) { 9287 if ('outerContent' in chunkConfig) { 9288 return chunkConfig.outerContent; 9289 } 9290 var props = this.props; 9291 var _a = this.state, forceYScrollbars = _a.forceYScrollbars, scrollerClientWidths = _a.scrollerClientWidths, scrollerClientHeights = _a.scrollerClientHeights; 9292 var needsYScrolling = getAllowYScrolling(props, sectionConfig); // TODO: do lazily. do in section config? 9293 var isLiquid = getSectionHasLiquidHeight(props, sectionConfig); 9294 // for `!props.liquid` - is WHOLE scrollgrid natural height? 9295 // TODO: do same thing in advanced scrollgrid? prolly not b/c always has horizontal scrollbars 9296 var overflowY = !props.liquid ? 'visible' : 9297 forceYScrollbars ? 'scroll' : 9298 !needsYScrolling ? 'hidden' : 9299 'auto'; 9300 var sectionKey = sectionConfig.key; 9301 var content = renderChunkContent(sectionConfig, chunkConfig, { 9302 tableColGroupNode: microColGroupNode, 9303 tableMinWidth: '', 9304 clientWidth: (!props.collapsibleWidth && scrollerClientWidths[sectionKey] !== undefined) ? scrollerClientWidths[sectionKey] : null, 9305 clientHeight: scrollerClientHeights[sectionKey] !== undefined ? scrollerClientHeights[sectionKey] : null, 9306 expandRows: sectionConfig.expandRows, 9307 syncRowHeights: false, 9308 rowSyncHeights: [], 9309 reportRowHeightChange: function () { }, 9310 }, isHeader); 9311 return createElement(isHeader ? 'th' : 'td', { 9312 ref: chunkConfig.elRef, 9313 role: 'presentation', 9314 }, createElement("div", { className: "fc-scroller-harness" + (isLiquid ? ' fc-scroller-harness-liquid' : '') }, 9315 createElement(Scroller, { ref: this.scrollerRefs.createRef(sectionKey), elRef: this.scrollerElRefs.createRef(sectionKey), overflowY: overflowY, overflowX: !props.liquid ? 'visible' : 'hidden' /* natural height? */, maxHeight: sectionConfig.maxHeight, liquid: isLiquid, liquidIsAbsolute // because its within a harness 9316 : true }, content))); 9317 }; 9318 SimpleScrollGrid.prototype._handleScrollerEl = function (scrollerEl, key) { 9319 var section = getSectionByKey(this.props.sections, key); 9320 if (section) { 9321 setRef(section.chunk.scrollerElRef, scrollerEl); 9322 } 9323 }; 9324 SimpleScrollGrid.prototype.componentDidMount = function () { 9325 this.handleSizing(); 9326 this.context.addResizeHandler(this.handleSizing); 9327 }; 9328 SimpleScrollGrid.prototype.componentDidUpdate = function () { 9329 // TODO: need better solution when state contains non-sizing things 9330 this.handleSizing(); 9331 }; 9332 SimpleScrollGrid.prototype.componentWillUnmount = function () { 9333 this.context.removeResizeHandler(this.handleSizing); 9334 }; 9335 SimpleScrollGrid.prototype.computeShrinkWidth = function () { 9336 return hasShrinkWidth(this.props.cols) 9337 ? computeShrinkWidth(this.scrollerElRefs.getAll()) 9338 : 0; 9339 }; 9340 SimpleScrollGrid.prototype.computeScrollerDims = function () { 9341 var scrollbarWidth = getScrollbarWidths(); 9342 var _a = this, scrollerRefs = _a.scrollerRefs, scrollerElRefs = _a.scrollerElRefs; 9343 var forceYScrollbars = false;
9344 var scrollerClientWidths = {}; 9345 var scrollerClientHeights = {}; 9346 for (var sectionKey in scrollerRefs.currentMap) { 9347 var scroller = scrollerRefs.currentMap[sectionKey]; 9348 if (scroller && scroller.needsYScrolling()) { 9349 forceYScrollbars = true; 9350 break; 9351 } 9352 } 9353 for (var _i = 0, _b = this.props.sections; _i < _b.length; _i++) { 9354 var section = _b[_i]; 9355 var sectionKey = section.key; 9356 var scrollerEl = scrollerElRefs.currentMap[sectionKey]; 9357 if (scrollerEl) { 9358 var harnessEl = scrollerEl.parentNode; // TODO: weird way to get this. need harness b/c doesn't include table borders 9359 scrollerClientWidths[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars 9360 ? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future 9361 : 0)); 9362 scrollerClientHeights[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().height); 9363 } 9364 } 9365 return { forceYScrollbars: forceYScrollbars, scrollerClientWidths: scrollerClientWidths, scrollerClientHeights: scrollerClientHeights }; 9366 }; 9367 return SimpleScrollGrid; 9368 }(BaseComponent)); 9369 SimpleScrollGrid.addStateEquality({ 9370 scrollerClientWidths: isPropsEqual, 9371 scrollerClientHeights: isPropsEqual, 9372 }); 9373 function getSectionByKey(sections, key) { 9374 for (var _i = 0, sections_1 = sections; _i < sections_1.length; _i++) { 9375 var section = sections_1[_i]; 9376 if (section.key === key) { 9377 return section; 9378 } 9379 } 9380 return null; 9381 } 9382 9383 var EventRoot = /** @class */ (function (_super) { 9384 __extends(EventRoot, _super); 9385 function EventRoot() { 9386 var _this = _super !== null && _super.apply(this, arguments) || this; 9387 _this.elRef = createRef(); 9388 return _this; 9389 } 9390 EventRoot.prototype.render = function () { 9391 var _a = this, props = _a.props, context = _a.context; 9392 var options = context.options; 9393 var seg = props.seg; 9394 var eventRange = seg.eventRange; 9395 var ui = eventRange.ui; 9396 var hookProps = { 9397 event: new EventApi(context, eventRange.def, eventRange.instance), 9398 view: context.viewApi, 9399 timeText: props.timeText, 9400 textColor: ui.textColor, 9401 backgroundColor: ui.backgroundColor, 9402 borderColor: ui.borderColor, 9403 isDraggable: !props.disableDragging && computeSegDraggable(seg, context), 9404 isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context), 9405 isEndResizable: !props.disableResizing && computeSegEndResizable(seg), 9406 isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting), 9407 isStart: Boolean(seg.isStart), 9408 isEnd: Boolean(seg.isEnd), 9409 isPast: Boolean(props.isPast), 9410 isFuture: Boolean(props.isFuture), 9411 isToday: Boolean(props.isToday), 9412 isSelected: Boolean(props.isSelected), 9413 isDragging: Boolean(props.isDragging), 9414 isResizing: Boolean(props.isResizing), 9415 }; 9416 var standardClassNames = getEventClassNames(hookProps).concat(ui.classNames); 9417 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.eventClassNames, content: options.eventContent, defaultContent: props.defaultContent, didMount: options.eventDidMount, willUnmount: options.eventWillUnmount, elRef: this.elRef }, function (rootElRef, customClassNames, innerElRef, innerContent) { return props.children(rootElRef, standardClassNames.c
9417oncat(customClassNames), innerElRef, innerContent, hookProps); })); 9418 }; 9419 EventRoot.prototype.componentDidMount = function () { 9420 setElSeg(this.elRef.current, this.props.seg); 9421 }; 9422 /* 9423 need to re-assign seg to the element if seg changes, even if the element is the same 9424 */ 9425 EventRoot.prototype.componentDidUpdate = function (prevProps) { 9426 var seg = this.props.seg; 9427 if (seg !== prevProps.seg) { 9428 setElSeg(this.elRef.current, seg); 9429 } 9430 }; 9431 return EventRoot; 9432 }(BaseComponent)); 9433 9434 // should not be a purecomponent 9435 var StandardEvent = /** @class */ (function (_super) { 9436 __extends(StandardEvent, _super); 9437 function StandardEvent() { 9438 return _super !== null && _super.apply(this, arguments) || this; 9439 } 9440 StandardEvent.prototype.render = function () { 9441 var _a = this, props = _a.props, context = _a.context; 9442 var seg = props.seg; 9443 var timeFormat = context.options.eventTimeFormat || props.defaultTimeFormat; 9444 var timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd); 9445 return (createElement(EventRoot, { seg: seg, timeText: timeText, disableDragging: props.disableDragging, disableResizing: props.disableResizing, defaultContent: props.defaultContent || renderInnerContent$4, isDragging: props.isDragging, isResizing: props.isResizing, isDateSelecting: props.isDateSelecting, isSelected: props.isSelected, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("a", __assign({ className: props.extraClassNames.concat(classNames).join(' '), style: { 9446 borderColor: hookProps.borderColor, 9447 backgroundColor: hookProps.backgroundColor, 9448 }, ref: rootElRef }, getSegAnchorAttrs(seg, context)), 9449 createElement("div", { className: "fc-event-main", ref: innerElRef, style: { color: hookProps.textColor } }, innerContent), 9450 hookProps.isStartResizable && 9451 createElement("div", { className: "fc-event-resizer fc-event-resizer-start" }), 9452 hookProps.isEndResizable && 9453 createElement("div", { className: "fc-event-resizer fc-event-resizer-end" }))); })); 9454 }; 9455 return StandardEvent; 9456 }(BaseComponent)); 9457 function renderInnerContent$4(innerProps) { 9458 return (createElement("div", { className: "fc-event-main-frame" }, 9459 innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)), 9460 createElement("div", { className: "fc-event-title-container" }, 9461 createElement("div", { className: "fc-event-title fc-sticky" }, innerProps.event.title || createElement(Fragment, null, "\u00A0"))))); 9462 } 9463 9464 var NowIndicatorRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) { 9465 var options = context.options; 9466 var hookProps = { 9467 isAxis: props.isAxis, 9468 date: context.dateEnv.toDate(props.date), 9469 view: context.viewApi, 9470 }; 9471 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.nowIndicatorClassNames, content: options.nowIndicatorContent, didMount: options.nowIndicatorDidMount, willUnmount: options.nowIndicatorWillUnmount }, props.children)); 9472 })); }; 9473 9474 var DAY_NUM_FORMAT = createFormatter({ day: 'numeric' }); 9475 var DayCellContent = /** @class */ (function (_super) { 9476 __extends(DayCellContent, _super); 9477 function DayCellContent() { 9478 return _super !== null && _super.apply(this, arguments) || this; 9479 } 9480 DayCellContent.prototype.render = function () { 9481 var _a = this, props = _a.props, context = _a.context; 9482 var options = context.options; 9483 var hookProps = refineDayCellHookProps({ 9484 date: props.date, 9485 dateProfile: props.dateProfile, 9486 todayRange: props.todayRange, 9487 showDayNumber: props.showDayNumber, 9488 extraProps: props.extraHookProps, 9489 viewApi: context.viewApi, 9490 dateEnv: context.dateEnv, 9491 }); 9492 return (createElement(ContentHook, { hookProps: hookProps, content: options.dayCellContent, defaultContent: props.defaultContent }, props.children)); 9493 }; 9494 return DayCellContent; 9495 }(BaseComponent)); 9496 function refineDayCellHookProps(raw) { 9497 var date = raw.date, dateEnv = raw.dateEnv;
9498 var dayMeta = getDateMeta(date, raw.todayRange, null, raw.dateProfile); 9499 return __assign(__assign(__assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), { dayNumberText: raw.showDayNumber ? dateEnv.format(date, DAY_NUM_FORMAT).replaceAll("ì¼", "") : '' }), raw.extraProps); 9500 } 9501 9502 var DayCellRoot = /** @class */ (function (_super) { 9503 __extends(DayCellRoot, _super); 9504 function DayCellRoot() { 9505 var _this = _super !== null && _super.apply(this, arguments) || this; 9506 _this.refineHookProps = memoizeObjArg(refineDayCellHookProps); 9507 _this.normalizeClassNames = buildClassNameNormalizer(); 9508 return _this; 9509 } 9510 DayCellRoot.prototype.render = function () { 9511 var _a = this, props = _a.props, context = _a.context; 9512 var options = context.options; 9513 var hookProps = this.refineHookProps({ 9514 date: props.date, 9515 dateProfile: props.dateProfile, 9516 todayRange: props.todayRange, 9517 showDayNumber: props.showDayNumber, 9518 extraProps: props.extraHookProps, 9519 viewApi: context.viewApi, 9520 dateEnv: context.dateEnv, 9521 }); 9522 var classNames = getDayClassNames(hookProps, context.theme).concat(hookProps.isDisabled 9523 ? [] // don't use custom classNames if disabled 9524 : this.normalizeClassNames(options.dayCellClassNames, hookProps)); 9525 var dataAttrs = hookProps.isDisabled ? {} : { 9526 'data-date': formatDayString(props.date), 9527 }; 9528 return (createElement(MountHook, { hookProps: hookProps, didMount: options.dayCellDidMount, willUnmount: options.dayCellWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, classNames, dataAttrs, hookProps.isDisabled); })); 9529 }; 9530 return DayCellRoot; 9531 }(BaseComponent)); 9532 9533 function renderFill(fillType) { 9534 return (createElement("div", { className: "fc-" + fillType })); 9535 } 9536 var BgEvent = function (props) { return (createElement(EventRoot, { defaultContent: renderInnerContent$3, seg: props.seg /* uselesss i think */, timeText: "", disableDragging: true, disableResizing: true, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("div", { ref: rootElRef, className: ['fc-bg-event'].concat(classNames).join(' '), style: { 9537 backgroundColor: hookProps.backgroundColor, 9538 } }, innerContent)); })); }; 9539 function renderInnerContent$3(props) { 9540 var title = props.event.title; 9541 return title && (createElement("div", { className: "fc-event-title" }, props.event.title)); 9542 } 9543 9544 var WeekNumberRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) { 9545 var dateEnv = context.dateEnv, options = context.options; 9546 var date = props.date; 9547 var format = options.weekNumberFormat || props.defaultFormat; 9548 var num = dateEnv.computeWeekNumber(date); // TODO: somehow use for formatting as well? 9549 var text = dateEnv.format(date, format); 9550 var hookProps = { num: num, text: text, date: date }; 9551 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.weekNumberClassNames, content: options.weekNumberContent, defaultContent: renderInner, didMount: options.weekNumberDidMount, willUnmount: options.weekNumberWillUnmount }, props.children)); 9552 })); }; 9553 function renderInner(innerProps) { 9554 return innerProps.text; 9555 } 9556 9557 var PADDING_FROM_VIEWPORT = 10; 9558 var Popover = /** @class */ (function (_super) { 9559 __extends(Popover, _super); 9560 function Popover() { 9561 var _this = _super !== null && _super.apply(this, arguments) || this; 9562 _this.state = { 9563 titleId: getUniqueDomId(), 9564 }; 9565 _this.handleRootEl = function (el) { 9566 _this.rootEl = el; 9567 if (_this.props.elRef) { 9568 setRef(_this.props.elRef, el); 9569 } 9570 }; 9571 // Triggered when the user clicks *anywhere* in the document, for the autoHide feature 9572 _this.handleDocumentMouseDown = function (ev) { 9573 // only hide the popover if the click happened outside the popover 9574 var target = getEventTargetViaRoot(ev); 9575 if (!_this.rootEl.contains(target)) { 9576 _this.handleCloseClick(); 9577 } 9578 }; 9579 _this.handleDocumentKeyDown = function (ev) { 9580 if (ev.key === 'Escape') { 9581 _this.handleCloseClick(); 9582 } 9583 }; 9584 _this.handleCloseClick = function () { 9585 var onClose = _this.props.onClose; 9586 if (onClose) { 9587 onClose(); 9588 } 9589 }; 9590 return _this; 9591 } 9592 Popover.prototype.render = function () { 9593 var _a = this.context, theme = _a.theme, options = _a.options; 9594 var _b = this, props = _b.props, state = _b.state; 9595 var classNames = [ 9596 'fc-popover', 9597 theme.getClass('popover'), 9598 ].concat(props.extraClassNames || []); 9599 return createPortal(createElement("div", __assign({ id: props.id, className: classNames.join(' '), "aria-labelledby": state.t
9599itleId }, props.extraAttrs, { ref: this.handleRootEl }), 9600 createElement("div", { className: 'fc-popover-header ' + theme.getClass('popoverHeader') }, 9601 createElement("span", { className: "fc-popover-title", id: state.titleId }, props.title), 9602 createElement("span", { className: 'fc-popover-close ' + theme.getIconClass('close'), title: options.closeHint, onClick: this.handleCloseClick })), 9603 createElement("div", { className: 'fc-popover-body ' + theme.getClass('popoverContent') }, props.children)), props.parentEl); 9604 }; 9605 Popover.prototype.componentDidMount = function () { 9606 document.addEventListener('mousedown', this.handleDocumentMouseDown); 9607 document.addEventListener('keydown', this.handleDocumentKeyDown); 9608 this.updateSize(); 9609 }; 9610 Popover.prototype.componentWillUnmount = function () { 9611 document.removeEventListener('mousedown', this.handleDocumentMouseDown); 9612 document.removeEventListener('keydown', this.handleDocumentKeyDown); 9613 }; 9614 Popover.prototype.updateSize = function () { 9615 var isRtl = this.context.isRtl; 9616 var _a = this.props, alignmentEl = _a.alignmentEl, alignGridTop = _a.alignGridTop; 9617 var rootEl = this.rootEl; 9618 var alignmentRect = computeClippedClientRect(alignmentEl); 9619 if (alignmentRect) { 9620 var popoverDims = rootEl.getBoundingClientRect(); 9621 // position relative to viewport 9622 var popoverTop = alignGridTop 9623 ? elementClosest(alignmentEl, '.fc-scrollgrid').getBoundingClientRect().top 9624 : alignmentRect.top; 9625 var popoverLeft = isRtl ? alignmentRect.right - popoverDims.width : alignmentRect.left; 9626 // constrain 9627 popoverTop = Math.max(popoverTop, PADDING_FROM_VIEWPORT); 9628 popoverLeft = Math.min(popoverLeft, document.documentElement.clientWidth - PADDING_FROM_VIEWPORT - popoverDims.width); 9629 popoverLeft = Math.max(popoverLeft, PADDING_FROM_VIEWPORT); 9630 var origin_1 = rootEl.offsetParent.getBoundingClientRect(); 9631 applyStyle(rootEl, { 9632 top: popoverTop - origin_1.top, 9633 left: popoverLeft - origin_1.left, 9634 }); 9635 } 9636 }; 9637 return Popover; 9638 }(BaseComponent)); 9639 9640 var MorePopover = /** @class */ (function (_super) { 9641 __extends(MorePopover, _super); 9642 function MorePopover() { 9643 var _this = _super !== null && _super.apply(this, arguments) || this; 9644 _this.handleRootEl = function (rootEl) { 9645 _this.rootEl = rootEl; 9646 if (rootEl) { 9647 _this.context.registerInteractiveComponent(_this, { 9648 el: rootEl, 9649 useEventCenter: false, 9650 }); 9651 } 9652 else { 9653 _this.context.unregisterInteractiveComponent(_this); 9654 } 9655 }; 9656 return _this; 9657 } 9658 MorePopover.prototype.render = function () { 9659 var _a = this.context, options = _a.options, dateEnv = _a.dateEnv; 9660 var props = this.props; 9661 var startDate = props.startDate, todayRange = props.todayRange, dateProfile = props.dateProfile; 9662 var title = dateEnv.format(startDate, options.dayPopoverFormat); 9663 return (createElement(DayCellRoot, { date: startDate, dateProfile: dateProfile, todayRange: todayRange, elRef: this.handleRootEl }, function (rootElRef, dayClassNames, dataAttrs) { return (createElement(Popover, { elRef: rootElRef, id: props.id, title: title, extraClassNames: ['fc-more-popover'].concat(dayClassNames), extraAttrs: dataAttrs /* TODO: make these time-based when not whole-day? */, parentEl: props.parentEl, alignmentEl: props.alignmentEl, alignGridTop: props.alignGridTop, onClose: props.onClose }, 9664 createElement(DayCellContent, { date: startDate, dateProfile: dateProfile, todayRange: todayRange }, function (innerElRef, innerContent) { return (innerContent && 9665 createElement("div", { className: "fc-more-popover-misc", ref: innerElRef }, innerContent)); }), 9666 props.children)); })); 9667 }; 9668 MorePopover.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) { 9669 var _a = this, rootEl = _a.rootEl, props = _a.props; 9670 if (positionLeft >= 0 && positionLeft < elWidth && 9671 positionTop >= 0 && positionTop < elHeight) { 9672 return { 9673 dateProfile: props.dateProfile, 9674 dateSpan: __assign({ allDay: true, range: { 9675 start: props.startDate, 9676 end: props.endDate, 9677 } }, props.extraDateSpan), 9678 dayEl: rootEl, 9679 rect: { 9680 left: 0, 9681 top: 0, 9682 right: elWidth, 9683 bottom: elHeight, 9684 }, 9685 layer: 1, // important when comparing with hits from other components 9686 }; 9687 } 9688 return null; 9689 }; 9690 return MorePopover; 9691 }(DateComponent)); 9692 9693 var MoreLinkRoot = /** @class */ (function (_super) { 9694 __extends(MoreLinkRoot, _super); 9695 function MoreLinkRoot() { 9696 var _this = _super !== null && _super.apply(this, arguments) || this; 9697 _this.linkElRef = createRef(); 9698 _this.state = { 9699 isPopoverOpen: false, 9700 popoverId: getUniqueDomId(), 9701 }; 9702 _this.handleClick = function (ev) { 9703 var _a = _this, props = _a.props, context = _a.context; 9704 var moreLinkClick = context.options.moreLinkClick; 9705 var date = computeRange(props).start; 9706 function buildPublicSeg(seg) { 9707 var _a = seg.eventRange, def = _a.def, instance = _a.instance, range = _a.range; 9708 return { 9709 event: new EventApi(context, def, instance), 9710 start: context.dateEnv.toDate(range.start), 9711 end: context.dateEnv.toDate(range.end), 9712 isStart: seg.isStart, 9713 isEnd: seg.isEnd, 9714 }; 9715 } 9716 if (typeof moreLinkClick === 'function') { 9717 moreLinkClick = moreLinkClick({ 9718 date: date, 9719 allDay: Boolean(props.allDayDate), 9720 allSegs: props.allSegs.map(buildPublicSeg), 9721 hiddenSegs: props.hiddenSegs.map(buildPublicSeg), 9722 jsEvent: ev, 9723 view: context.viewApi, 9724 }); 9725 } 9726 if (!moreLinkClick || moreLinkClick === 'popover') { 9727 _this.setState({ isPopoverOpen: true });
9728 } 9729 else if (typeof moreLinkClick === 'string') { // a view name 9730 context.calendarApi.zoomTo(date, moreLinkClick); 9731 } 9732 }; 9733 _this.handlePopoverClose = function () { 9734 _this.setState({ isPopoverOpen: false }); 9735 }; 9736 return _this; 9737 } 9738 MoreLinkRoot.prototype.render = function () { 9739 var _this = this; 9740 var _a = this, props = _a.props, state = _a.state; 9741 return (createElement(ViewContextType.Consumer, null, function (context) { 9742 var viewApi = context.viewApi, options = context.options, calendarApi = context.calendarApi; 9743 var moreLinkText = options.moreLinkText; 9744 var moreCnt = props.moreCnt; 9745 var range = computeRange(props); 9746 var text = typeof moreLinkText === 'function' // TODO: eventually use formatWithOrdinals 9747 ? moreLinkText.call(calendarApi, moreCnt) 9748 : "+" + moreCnt + " " + moreLinkText; 9749 var title = formatWithOrdinals(options.moreLinkHint, [moreCnt], text); 9750 var hookProps = { 9751 num: moreCnt, 9752 shortText: "+" + moreCnt, 9753 text: text, 9754 view: viewApi, 9755 }; 9756 return (createElement(Fragment, null, 9757 Boolean(props.moreCnt) && (createElement(RenderHook, { elRef: _this.linkElRef, hookProps: hookProps, classNames: options.moreLinkClassNames, content: options.moreLinkContent, defaultContent: props.defaultContent || renderMoreLinkInner$1, didMount: options.moreLinkDidMount, willUnmount: options.moreLinkWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return props.children(rootElRef, ['fc-more-link'].concat(customClassNames), innerElRef, innerContent, _this.handleClick, title, state.isPopoverOpen, state.isPopoverOpen ? state.popoverId : ''); })), 9758 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.current, alignGridTop: props.alignGridTop, onClose: _this.handlePopoverClose }, props.popoverContent())))); 9759 })); 9760 }; 9761 MoreLinkRoot.prototype.componentDidMount = function () { 9762 this.updateParentEl(); 9763 }; 9764 MoreLinkRoot.prototype.componentDidUpdate = function () { 9765 this.updateParentEl(); 9766 }; 9767 MoreLinkRoot.prototype.updateParentEl = function () { 9768 if (this.linkElRef.current) { 9769 this.parentEl = elementClosest(this.linkElRef.current, '.fc-view-harness'); 9770 } 9771 }; 9772 return MoreLinkRoot; 9773 }(BaseComponent)); 9774 function renderMoreLinkInner$1(props) { 9775 return props.text; 9776 } 9777 function computeRange(props) { 9778 if (props.allDayDate) { 9779 return { 9780 start: props.allDayDate, 9781 end: addDays(props.allDayDate, 1), 9782 }; 9783 } 9784 var hiddenSegs = props.hiddenSegs; 9785 return { 9786 start: computeEarliestSegStart(hiddenSegs), 9787 end: computeLatestSegEnd(hiddenSegs), 9788 }; 9789 } 9790 function computeEarliestSegStart(segs) { 9791 return segs.reduce(pickEarliestStart).eventRange.range.start; 9792 } 9793 function pickEarliestStart(seg0, seg1) { 9794 return seg0.eventRange.range.start < seg1.eventRange.range.start ? seg0 : seg1; 9795 } 9796 function computeLatestSegEnd(segs) { 9797 return segs.reduce(pickLatestEnd).eventRange.range.end; 9798 } 9799 function pickLatestEnd(seg0, seg1) { 9800 return seg0.eventRange.range.end > seg1.eventRange.range.end ? seg0 : seg1; 9801 } 9802 9803 // exports 9804 // -------------------------------------------------------------------------------------------------- 9805 var version = '5.11.0'; // important to type it, so .d.ts has generic string 9806 9807 var Calendar = /** @class */ (function (_super) { 9808 __extends(Calendar, _super); 9809 function Calendar(el, optionOverrides) { 9810 if (optionOverrides === void 0) { optionOverrides = {}; } 9811 var _this = _super.call(this) || this; 9812 _this.isRendering = false; 9813 _this.isRendered = false; 9814 _this.currentClassNames = []; 9815 _this.customContentRenderId = 0; // will affect custom generated classNames? 9816 _this.handleAction = function (action) {
9817 // actions we know we want to render immediately 9818 switch (action.type) { 9819 case 'SET_EVENT_DRAG': 9820 case 'SET_EVENT_RESIZE': 9821 _this.renderRunner.tryDrain(); 9822 } 9823 }; 9824 _this.handleData = function (data) { 9825 _this.currentData = data; 9826 _this.renderRunner.request(data.calendarOptions.rerenderDelay); 9827 }; 9828 _this.handleRenderRequest = function () { 9829 if (_this.isRendering) { 9830 _this.isRendered = true; 9831 var currentData_1 = _this.currentData; 9832 flushSync(function () { 9833 render(createElement(CalendarRoot, { options: currentData_1.calendarOptions, theme: currentData_1.theme, emitter: currentData_1.emitter }, function (classNames, height, isHeightAuto, forPrint) { 9834 _this.setClassNames(classNames); 9835 _this.setHeight(height); 9836 return (createElement(CustomContentRenderContext.Provider, { value: _this.customContentRenderId }, 9837 createElement(CalendarContent, __assign({ isHeightAuto: isHeightAuto, forPrint: forPrint }, currentData_1)))); 9838 }), _this.el); 9839 }); 9840 } 9841 else if (_this.isRendered) { 9842 _this.isRendered = false; 9843 unmountComponentAtNode(_this.el); 9844 _this.setClassNames([]); 9845 _this.setHeight(''); 9846 } 9847 }; 9848 _this.el = el; 9849 _this.renderRunner = new DelayedRunner(_this.handleRenderRequest); 9850 new CalendarDataManager({ 9851 optionOverrides: optionOverrides, 9852 calendarApi: _this, 9853 onAction: _this.handleAction, 9854 onData: _this.handleData, 9855 }); 9856 return _this; 9857 } 9858 Object.defineProperty(Calendar.prototype, "view", { 9859 get: function () { return this.currentData.viewApi; } // for public API 9860 , 9861 enumerable: false, 9862 configurable: true 9863 }); 9864 Calendar.prototype.render = function () { 9865 var wasRendering = this.isRendering; 9866 if (!wasRendering) { 9867 this.isRendering = true; 9868 } 9869 else { 9870 this.customContentRenderId += 1; 9871 } 9872 this.renderRunner.request(); 9873 if (wasRendering) { 9874 this.updateSize(); 9875 } 9876 }; 9877 Calendar.prototype.destroy = function () { 9878 if (this.isRendering) { 9879 this.isRendering = false; 9880 this.renderRunner.request(); 9881 } 9882 }; 9883 Calendar.prototype.updateSize = function () { 9884 var _this = this; 9885 flushSync(function () { 9886 _super.prototype.updateSize.call(_this); 9887 }); 9888 }; 9889 Calendar.prototype.batchRendering = function (func) { 9890 this.renderRunner.pause('batchRendering'); 9891 func(); 9892 this.renderRunner.resume('batchRendering'); 9893 }; 9894 Calendar.prototype.pauseRendering = function () { 9895 this.renderRunner.pause('pauseRendering'); 9896 }; 9897 Calendar.prototype.resumeRendering = function () { 9898 this.renderRunner.resume('pauseRendering', true); 9899 }; 9900 Calendar.prototype.resetOptions = function (optionOverrides, append) { 9901 this.currentDataManager.resetOptions(optionOverrides, append); 9902 }; 9903 Calendar.prototype.setClassNames = function (classNames) { 9904 if (!isArraysEqual(classNames, this.currentClassNames)) { 9905 var classList = this.el.classList; 9906 for (var _i = 0, _a = this.currentClassNames; _i < _a.length; _i++) { 9907 var className = _a[_i]; 9908 classList.remove(className); 9909 } 9910 for (var _b = 0, classNames_1 = classNames; _b < classNames_1.length; _b++) { 9911 var className = classNames_1[_b]; 9912 classList.add(className); 9913 } 9914 this.currentClassNames = classNames; 9915 } 9916 }; 9917 Calendar.prototype.setHeight = function (height) { 9918 applyStyleProp(this.el, 'height', height); 9919 }; 9920 return Calendar; 9921 }(CalendarApi)); 9922 9923 config.touchMouseIgnoreWait = 500; 9924 var ignoreMouseDepth = 0; 9925 var listenerCnt = 0; 9926 var isWindowTouchMoveCancelled = false; 9927 /* 9928 Uses a "pointer" abstraction, which monitors UI events for both mouse and touch. 9929 Tracks when the pointer "drags" on a certain element, meaning down+move+up. 9930 9931 Also, tracks if there was touch-scrolling. 9932 Also, can prevent touch-scrolling from happening. 9933 Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement. 9934 9935 emits: 9936 - pointerdown 9937 - pointermove 9938 - pointerup 9939 */ 9940 var PointerDragging = /** @class */ (function () { 9941 function PointerDragging(containerEl) { 9942 var _this = this; 9943 this.subjectEl = null; 9944 // options that can be directly assigned by caller 9945 this.selector = ''; // will cause subjectEl in all emitted events to be this element 9946 this.handleSelector = ''; 9947 this.shouldIgnoreMove = false; 9948 this.shouldWatchScroll = true; // for simulating pointermove on scroll 9949 // internal states 9950 this.isDragging = false; 9951 this.isTouchDragging = false; 9952 this.wasTouchScroll = false; 9953 // Mouse 9954 // ---------------------------------------------------------------------------------------------------- 9955 this.handleMouseDown = function (ev) { 9956 if (!_this.shouldIgnoreMouse() && 9957 isPrimaryMouseButton(ev) && 9958 _this.tryStart(ev)) { 9959 var pev = _this.createEventFromMouse(ev, true); 9960 _this.emitter.trigger('pointerdown', pev); 9961 _this.initScrollWatch(pev); 9962 if (!_this.shouldIgnoreMove) { 9963 document.addEventListener('mousemove', _this.handleMouseMove); 9964 } 9965 document.addEventListener('mouseup', _this.handleMouseUp); 9966 } 9967 }; 9968 this.handleMouseMove = function (ev) { 9969 var pev = _this.createEventFromMouse(ev); 9970 _this.recordCoords(pev); 9971 _this.emitter.trigger('pointermove', pev); 9972 }; 9973 this.handleMouseUp = function (ev) { 9974 document.removeEventListener('mousemove', _this.handleMouseMove); 9975 document.removeEventListener('mouseup', _this.handleMouseUp); 9976 _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev)); 9977 _this.cleanup(); // call last so that pointerup has access to props 9978 }; 9979 // Touch 9980 // ---------------------------------------------------------------------------------------------------- 9981 this.handleTouchStart = function (ev) { 9982 if (_this.tryStart(ev)) { 9983 _this.isTouchDragging = true; 9984 var pev = _this.createEventFromTouch(ev, true); 9985 _this.emitter.trigger('pointerdown', pev); 9986 _this.initScrollWatch(pev); 9987 // unlike mouse, need to attach to target, not document 9988 // https://stackoverflow.com/a/45760014 9989 var targetEl = ev.target; 9990 if (!_this.shouldIgnoreMove) { 9991 targetEl.addEventListener('touchmove', _this.handleTouchMove); 9992 } 9993 targetEl.addEventListener('touchend', _this.handleTouchEnd); 9994 targetEl.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end 9995 // attach a handler to get called when ANY scroll action happens on the page. 9996 // this was impossible to do with normal on/off because 'scroll' doesn't bubble. 9997 // http://stackoverflow.com/a/32954565/96342 9998 window.addEventListener('scroll', _this.handleTouchScroll, true); 9999 } 10000 }; 10001 this.handleTouchMove = function (ev) { 10002 var pev = _this.createEventFromTouch(ev); 10003 _this.recordCoords(pev); 10004 _this.emitter.trigger('pointermove', pev); 10005 }; 10006 this.handleTouchEnd = function (ev) { 10007 if (_this.isDragging) { // done to guard against touchend followed by touchcancel 10008 var targetEl = ev.target; 10009 targetEl.removeEventListener('touchmove', _this.handleTouchMove); 10010 targetEl.removeEventListener('touchend', _this.handleTouchEnd); 10011 targetEl.removeEventListener('touchcancel', _this.handleTouchEnd); 10012 window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true 10013 _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev)); 10014 _this.cleanup(); // call last so that pointerup has access to props 10015 _this.isTouchDragging = false; 10016 startIgnoringMouse(); 10017 } 10018 }; 10019 this.handleTouchScroll = function () { 10020 _this.wasTouchScroll = true; 10021 }; 10022 this.handleScroll = function (ev) { 10023 if (!_this.shouldIgnoreMove) { 10024 var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX; 10025 var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY; 10026 _this.emitter.trigger('pointermove', { 10027 origEvent: ev, 10028 isTouch: _this.isTouchDragging, 10029 subjectEl: _this.subjectEl, 10030 pageX: pageX, 10031 pageY: pageY, 10032 deltaX: pageX - _this.origPageX, 10033 deltaY: pageY - _this.origPageY, 10034 }); 10035 } 10036 }; 10037 this.containerEl = containerEl; 10038 this.emitter = new Emitter(); 10039 containerEl.addEventListener('mousedown', this.handleMouseDown);
10040 containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true }); 10041 listenerCreated(); 10042 } 10043 PointerDragging.prototype.destroy = function () { 10044 this.containerEl.removeEventListener('mousedown', this.handleMouseDown); 10045 this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true }); 10046 listenerDestroyed(); 10047 }; 10048 PointerDragging.prototype.tryStart = function (ev) { 10049 var subjectEl = this.querySubjectEl(ev); 10050 var downEl = ev.target; 10051 if (subjectEl && 10052 (!this.handleSelector || elementClosest(downEl, this.handleSelector))) { 10053 this.subjectEl = subjectEl; 10054 this.isDragging = true; // do this first so cancelTouchScroll will work 10055 this.wasTouchScroll = false; 10056 return true; 10057 } 10058 return false; 10059 }; 10060 PointerDragging.prototype.cleanup = function () { 10061 isWindowTouchMoveCancelled = false; 10062 this.isDragging = false; 10063 this.subjectEl = null; 10064 // keep wasTouchScroll around for later access 10065 this.destroyScrollWatch(); 10066 }; 10067 PointerDragging.prototype.querySubjectEl = function (ev) { 10068 if (this.selector) { 10069 return elementClosest(ev.target, this.selector); 10070 } 10071 return this.containerEl; 10072 }; 10073 PointerDragging.prototype.shouldIgnoreMouse = function () { 10074 return ignoreMouseDepth || this.isTouchDragging; 10075 }; 10076 // can be called by user of this class, to cancel touch-based scrolling for the current drag 10077 PointerDragging.prototype.cancelTouchScroll = function () { 10078 if (this.isDragging) { 10079 isWindowTouchMoveCancelled = true; 10080 } 10081 }; 10082 // Scrolling that simulates pointermoves 10083 // ---------------------------------------------------------------------------------------------------- 10084 PointerDragging.prototype.initScrollWatch = function (ev) { 10085 if (this.shouldWatchScroll) { 10086 this.recordCoords(ev); 10087 window.addEventListener('scroll', this.handleScroll, true); // useCapture=true 10088 } 10089 }; 10090 PointerDragging.prototype.recordCoords = function (ev) { 10091 if (this.shouldWatchScroll) { 10092 this.prevPageX = ev.pageX; 10093 this.prevPageY = ev.pageY; 10094 this.prevScrollX = window.pageXOffset; 10095 this.prevScrollY = window.pageYOffset; 10096 } 10097 }; 10098 PointerDragging.prototype.destroyScrollWatch = function () { 10099 if (this.shouldWatchScroll) { 10100 window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true 10101 } 10102 }; 10103 // Event Normalization 10104 // ---------------------------------------------------------------------------------------------------- 10105 PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) { 10106 var deltaX = 0; 10107 var deltaY = 0; 10108 // TODO: repeat code 10109 if (isFirst) { 10110 this.origPageX = ev.pageX; 10111 this.origPageY = ev.pageY; 10112 } 10113 else { 10114 deltaX = ev.pageX - this.origPageX; 10115 deltaY = ev.pageY - this.origPageY; 10116 } 10117 return { 10118 origEvent: ev, 10119 isTouch: false, 10120 subjectEl: this.subjectEl, 10121 pageX: ev.pageX, 10122 pageY: ev.pageY, 10123 deltaX: deltaX, 10124 deltaY: deltaY, 10125 }; 10126 }; 10127 PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) { 10128 var touches = ev.touches; 10129 var pageX; 10130 var pageY; 10131 var deltaX = 0; 10132 var deltaY = 0; 10133 // if touch coords available, prefer, 10134 // because FF would give bad ev.pageX ev.pageY 10135 if (touches && touches.length) { 10136 pageX = touches[0].pageX; 10137 pageY = touches[0].pageY; 10138 } 10139 else { 10140 pageX = ev.pageX; 10141 pageY = ev.pageY; 10142 } 10143 // TODO: repeat code 10144 if (isFirst) { 10145 this.origPageX = pageX; 10146 this.origPageY = pageY; 10147 } 10148 else { 10149 deltaX = pageX - this.origPageX; 10150 deltaY = pageY - this.origPageY; 10151 } 10152 return { 10153 origEvent: ev, 10154 isTouch: true, 10155 subjectEl: this.subjectEl, 10156 pageX: pageX, 10157 pageY: pageY, 10158 deltaX: deltaX, 10159 deltaY: deltaY, 10160 }; 10161 }; 10162 return PointerDragging; 10163 }());
10164 // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac) 10165 function isPrimaryMouseButton(ev) { 10166 return ev.button === 0 && !ev.ctrlKey; 10167 } 10168 // Ignoring fake mouse events generated by touch 10169 // ---------------------------------------------------------------------------------------------------- 10170 function startIgnoringMouse() { 10171 ignoreMouseDepth += 1; 10172 setTimeout(function () { 10173 ignoreMouseDepth -= 1; 10174 }, config.touchMouseIgnoreWait); 10175 } 10176 // We want to attach touchmove as early as possible for Safari 10177 // ---------------------------------------------------------------------------------------------------- 10178 function listenerCreated() { 10179 listenerCnt += 1; 10180 if (listenerCnt === 1) { 10181 window.addEventListener('touchmove', onWindowTouchMove, { passive: false }); 10182 } 10183 } 10184 function listenerDestroyed() { 10185 listenerCnt -= 1; 10186 if (!listenerCnt) { 10187 window.removeEventListener('touchmove', onWindowTouchMove, { passive: false }); 10188 } 10189 } 10190 function onWindowTouchMove(ev) { 10191 if (isWindowTouchMoveCancelled) { 10192 ev.preventDefault(); 10193 } 10194 } 10195 10196 /* 10197 An effect in which an element follows the movement of a pointer across the screen. 10198 The moving element is a clone of some other element. 10199 Must call start + handleMove + stop. 10200 */ 10201 var ElementMirror = /** @class */ (function () { 10202 function ElementMirror() { 10203 this.isVisible = false; // must be explicitly enabled 10204 this.sourceEl = null; 10205 this.mirrorEl = null; 10206 this.sourceElRect = null; // screen coords relative to viewport 10207 // options that can be set directly by caller 10208 this.parentNode = document.body; // HIGHLY SUGGESTED to set this to sidestep ShadowDOM issues 10209 this.zIndex = 9999; 10210 this.revertDuration = 0; 10211 } 10212 ElementMirror.prototype.start = function (sourceEl, pageX, pageY) { 10213 this.sourceEl = sourceEl; 10214 this.sourceElRect = this.sourceEl.getBoundingClientRect(); 10215 this.origScreenX = pageX - window.pageXOffset; 10216 this.origScreenY = pageY - window.pageYOffset; 10217 this.deltaX = 0; 10218 this.deltaY = 0; 10219 this.updateElPosition(); 10220 }; 10221 ElementMirror.prototype.handleMove = function (pageX, pageY) { 10222 this.deltaX = (pageX - window.pageXOffset) - this.origScreenX; 10223 this.deltaY = (pageY - window.pageYOffset) - this.origScreenY; 10224 this.updateElPosition(); 10225 }; 10226 // can be called before start 10227 ElementMirror.prototype.setIsVisible = function (bool) { 10228 if (bool) { 10229 if (!this.isVisible) { 10230 if (this.mirrorEl) { 10231 this.mirrorEl.style.display = ''; 10232 } 10233 this.isVisible = bool; // needs to happen before updateElPosition 10234 this.updateElPosition(); // because was not updating the position while invisible 10235 } 10236 } 10237 else if (this.isVisible) { 10238 if (this.mirrorEl) { 10239 this.mirrorEl.style.display = 'none'; 10240 } 10241 this.isVisible = bool; 10242 } 10243 }; 10244 // always async 10245 ElementMirror.prototype.stop = function (needsRevertAnimation, callback) { 10246 var _this = this; 10247 var done = function () { 10248 _this.cleanup(); 10249 callback(); 10250 }; 10251 if (needsRevertAnimation && 10252 this.mirrorEl && 10253 this.isVisible && 10254 this.revertDuration && // if 0, transition won't work 10255 (this.deltaX || this.deltaY) // if same coords, transition won't work 10256 ) { 10257 this.doRevertAnimation(done, this.revertDuration); 10258 } 10259 else { 10260 setTimeout(done, 0); 10261 } 10262 }; 10263 ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) { 10264 var mirrorEl = this.mirrorEl; 10265 var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened 10266 mirrorEl.style.transition = 10267 'top ' + revertDuration + 'ms,' + 10268 'left ' + revertDuration + 'ms'; 10269 applyStyle(mirrorEl, { 10270 left: finalSourceElRect.left, 10271 top: finalSourceElRect.top, 10272 }); 10273 whenTransitionDone(mirrorEl, function () { 10274 mirrorEl.style.transition = ''; 10275 callback(); 10276 }); 10277 }; 10278 ElementMirror.prototype.cleanup = function () { 10279 if (this.mirrorEl) { 10280 removeElement(this.mirrorEl); 10281 this.mirrorEl = null; 10282 } 10283 this.sourceEl = null; 10284 }; 10285 ElementMirror.prototype.updateElPosition = function () { 10286 if (this.sourceEl && this.isVisible) { 10287 applyStyle(this.getMirrorEl(), { 10288 left: this.sourceElRect.left + this.deltaX, 10289 top: this.sourceElRect.top + this.deltaY, 10290 }); 10291 } 10292 }; 10293 ElementMirror.prototype.getMirrorEl = function () { 10294 var sourceElRect = this.sourceElRect; 10295 var mirrorEl = this.mirrorEl; 10296 if (!mirrorEl) { 10297 mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true 10298 // we don't want long taps or any mouse interaction causing selection/menus. 10299 // would use preventSelection(), but that prevents selectstart, causing problems. 10300 mirrorEl.classList.add('fc-unselectable'); 10301 mirrorEl.classList.add('fc-event-dragging'); 10302 applyStyle(mirrorEl, { 10303 position: 'fixed', 10304 zIndex: this.zIndex, 10305 visibility: '', 10306 boxSizing: 'border-box', 10307 width: sourceElRect.right - sourceElRect.left, 10308 height: sourceElRect.bottom - sourceElRect.top, 10309 right: 'auto', 10310 bottom: 'auto', 10311 margin: 0, 10312 }); 10313 this.parentNode.appendChild(mirrorEl); 10314 } 10315 return mirrorEl; 10316 }; 10317 return ElementMirror; 10318 }()); 10319 10320 /* 10321 Is a cache for a given element's scroll information (all the info that ScrollController stores) 10322 in addition the "client rectangle" of the element.. the area within the scrollbars. 10323 10324 The cache can be in one of two modes: 10325 - doesListening:false - ignores when the container is scrolled by someone else 10326 - doesListening:true - watch for scrolling and update the cache 10327 */ 10328 var ScrollGeomCache = /** @class */ (function (_super) { 10329 __extends(ScrollGeomCache, _super); 10330 function ScrollGeomCache(scrollController, doesListening) { 10331 var _this = _super.call(this) || this; 10332 _this.handleScroll = function () { 10333 _this.scrollTop = _this.scrollController.getScrollTop(); 10334 _this.scrollLeft = _this.scrollController.getScrollLeft(); 10335 _this.handleScrollChange(); 10336 };
10337 _this.scrollController = scrollController; 10338 _this.doesListening = doesListening; 10339 _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop(); 10340 _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft(); 10341 _this.scrollWidth = scrollController.getScrollWidth(); 10342 _this.scrollHeight = scrollController.getScrollHeight(); 10343 _this.clientWidth = scrollController.getClientWidth(); 10344 _this.clientHeight = scrollController.getClientHeight(); 10345 _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values 10346 if (_this.doesListening) { 10347 _this.getEventTarget().addEventListener('scroll', _this.handleScroll); 10348 } 10349 return _this; 10350 } 10351 ScrollGeomCache.prototype.destroy = function () { 10352 if (this.doesListening) { 10353 this.getEventTarget().removeEventListener('scroll', this.handleScroll); 10354 } 10355 }; 10356 ScrollGeomCache.prototype.getScrollTop = function () { 10357 return this.scrollTop; 10358 }; 10359 ScrollGeomCache.prototype.getScrollLeft = function () { 10360 return this.scrollLeft; 10361 }; 10362 ScrollGeomCache.prototype.setScrollTop = function (top) { 10363 this.scrollController.setScrollTop(top); 10364 if (!this.doesListening) { 10365 // we are not relying on the element to normalize out-of-bounds scroll values 10366 // so we need to sanitize ourselves 10367 this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0); 10368 this.handleScrollChange(); 10369 } 10370 }; 10371 ScrollGeomCache.prototype.setScrollLeft = function (top) { 10372 this.scrollController.setScrollLeft(top); 10373 if (!this.doesListening) { 10374 // we are not relying on the element to normalize out-of-bounds scroll values 10375 // so we need to sanitize ourselves 10376 this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0); 10377 this.handleScrollChange(); 10378 } 10379 }; 10380 ScrollGeomCache.prototype.getClientWidth = function () { 10381 return this.clientWidth; 10382 }; 10383 ScrollGeomCache.prototype.getClientHeight = function () { 10384 return this.clientHeight; 10385 }; 10386 ScrollGeomCache.prototype.getScrollWidth = function () { 10387 return this.scrollWidth; 10388 }; 10389 ScrollGeomCache.prototype.getScrollHeight = function () { 10390 return this.scrollHeight; 10391 }; 10392 ScrollGeomCache.prototype.handleScrollChange = function () { 10393 }; 10394 return ScrollGeomCache; 10395 }(ScrollController)); 10396 10397 var ElementScrollGeomCache = /** @class */ (function (_super) { 10398 __extends(ElementScrollGeomCache, _super); 10399 function ElementScrollGeomCache(el, doesListening) { 10400 return _super.call(this, new ElementScrollController(el), doesListening) || this; 10401 } 10402 ElementScrollGeomCache.prototype.getEventTarget = function () { 10403 return this.scrollController.el; 10404 }; 10405 ElementScrollGeomCache.prototype.computeClientRect = function () { 10406 return computeInnerRect(this.scrollController.el); 10407 }; 10408 return ElementScrollGeomCache; 10409 }(ScrollGeomCache)); 10410 10411 var WindowScrollGeomCache = /** @class */ (function (_super) { 10412 __extends(WindowScrollGeomCache, _super); 10413 function WindowScrollGeomCache(doesListening) { 10414 return _super.call(this, new WindowScrollController(), doesListening) || this; 10415 } 10416 WindowScrollGeomCache.prototype.getEventTarget = function () { 10417 return window; 10418 }; 10419 WindowScrollGeomCache.prototype.computeClientRect = function () { 10420 return { 10421 left: this.scrollLeft, 10422 right: this.scrollLeft + this.clientWidth, 10423 top: this.scrollTop, 10424 bottom: this.scrollTop + this.clientHeight, 10425 }; 10426 }; 10427 // the window is the only scroll object that changes it's rectangle relative 10428 // to the document's topleft as it scrolls 10429 WindowScrollGeomCache.prototype.handleScrollChange = function () { 10430 this.clientRect = this.computeClientRect(); 10431 }; 10432 return WindowScrollGeomCache; 10433 }(ScrollGeomCache)); 10434 10435 // If available we are using native "performance" API instead of "Date" 10436 // Read more about it on MDN: 10437 // https://developer.mozilla.org/en-US/docs/Web/API/Performance 10438 var getTime = typeof performance === 'function' ? performance.now : Date.now; 10439 /* 10440 For a pointer interaction, automatically scrolls certain scroll containers when the pointer 10441 approaches the edge. 10442 10443 The caller must call start + handleMove + stop. 10444 */ 10445 var AutoScroller = /** @class */ (function () { 10446 function AutoScroller() { 10447 var _this = this; 10448 // options that can be set by caller 10449 this.isEnabled = true; 10450 this.scrollQuery = [window, '.fc-scroller']; 10451 this.edgeThreshold = 50; // pixels 10452 this.maxVelocity = 300; // pixels per second 10453 // internal state 10454 this.pointerScreenX = null; 10455 this.pointerScreenY = null; 10456 this.isAnimating = false; 10457 this.scrollCaches = null; 10458 // protect against the initial pointerdown being too close to an edge and starting the scroll 10459 this.everMovedUp = false; 10460 this.everMovedDown = false; 10461 this.everMovedLeft = false; 10462 this.everMovedRight = false; 10463 this.animate = function () { 10464 if (_this.isAnimating) { // wasn't cancelled between animation calls 10465 var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset); 10466 if (edge) { 10467 var now = getTime(); 10468 _this.handleSide(edge, (now - _this.msSinceRequest) / 1000); 10469 _this.requestAnimation(now); 10470 } 10471 else { 10472 _this.isAnimating = false; // will stop animation 10473 } 10474 } 10475 }; 10476 } 10477 AutoScroller.prototype.start = function (pageX, pageY, scrollStartEl) { 10478 if (this.isEnabled) { 10479 this.scrollCaches = this.buildCaches(scrollStartEl); 10480 this.pointerScreenX = null; 10481 this.pointerScreenY = null; 10482 this.everMovedUp = false; 10483 this.everMovedDown = false; 10484 this.everMovedLeft = false; 10485 this.everMovedRight = false; 10486 this.handleMove(pageX, pageY); 10487 } 10488 }; 10489 AutoScroller.prototype.handleMove = function (pageX, pageY) { 10490 if (this.isEnabled) { 10491 var pointerScreenX = pageX - window.pageXOffset; 10492 var pointerScreenY = pageY - window.pageYOffset; 10493 var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY; 10494 var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX; 10495 if (yDelta < 0) { 10496 this.everMovedUp = true; 10497 } 10498 else if (yDelta > 0) { 10499 this.everMovedDown = true; 10500 } 10501 if (xDelta < 0) { 10502 this.everMovedLeft = true; 10503 } 10504 else if (xDelta > 0) { 10505 this.everMovedRight = true; 10506 } 10507 this.pointerScreenX = pointerScreenX; 10508 this.pointerScreenY = pointerScreenY; 10509 if (!this.isAnimating) { 10510 this.isAnimating = true; 10511 this.requestAnimation(getTime()); 10512 } 10513 } 10514 }; 10515 AutoScroller.prototype.stop = function () { 10516 if (this.isEnabled) { 10517 this.isAnimating = false; // will stop animation 10518 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10519 var scrollCache = _a[_i]; 10520 scrollCache.destroy(); 10521 } 10522 this.scrollCaches = null; 10523 } 10524 }; 10525 AutoScroller.prototype.requestAnimation = function (now) { 10526 this.msSinceRequest = now; 10527 requestAnimationFrame(this.animate); 10528 }; 10529 AutoScroller.prototype.handleSide = function (edge, seconds) { 10530 var scrollCache = edge.scrollCache; 10531 var edgeThreshold = this.edgeThreshold; 10532 var invDistance = edgeThreshold - edge.distance; 10533 var velocity = // the closer to the edge, the faster we scroll 10534 ((invDistance * invDistance) / (edgeThreshold * edgeThreshold)) * // quadratic 10535 this.maxVelocity * seconds; 10536 var sign = 1; 10537 switch (edge.name) { 10538 case 'left': 10539 sign = -1; 10540 // falls through 10541 case 'right': 10542 scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign); 10543 break; 10544 case 'top': 10545 sign = -1; 10546 // falls through 10547 case 'bottom': 10548 scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign); 10549 break; 10550 } 10551 }; 10552 // left/top are relative to document topleft 10553 AutoScroller.prototype.computeBestEdge = function (left, top) { 10554 var edgeThreshold = this.edgeThreshold; 10555 var bestSide = null; 10556 var scrollCaches = this.scrollCaches || []; 10557 for (var _i = 0, scrollCaches_1 = scrollCaches; _i < scrollCaches_1.length; _i++) { 10558 var scrollCache = scrollCaches_1[_i]; 10559 var rect = scrollCache.clientRect; 10560 var leftDist = left - rect.left; 10561 var rightDist = rect.right - left; 10562 var topDist = top - rect.top; 10563 var bottomDist = rect.bottom - top; 10564 // completely within the rect? 10565 if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) { 10566 if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() && 10567 (!bestSide || bestSide.distance > topDist)) { 10568 bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist }; 10569 } 10570 if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() && 10571 (!bestSide || bestSide.distance > bottomDist)) { 10572 bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist }; 10573 } 10574 if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() && 10575 (!bestSide || bestSide.distance > leftDist)) { 10576 bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist }; 10577 } 10578 if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() && 10579 (!bestSide || bestSide.distance > rightDist)) { 10580 bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist }; 10581 } 10582 } 10583 } 10584 return bestSide; 10585 }; 10586 AutoScroller.prototype.buildCaches = function (scrollStartEl) { 10587 return this.queryScrollEls(scrollStartEl).map(function (el) { 10588 if (el === window) { 10589 return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls 10590 } 10591 return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls 10592 }); 10593 }; 10594 AutoScroller.prototype.queryScrollEls = function (scrollStartEl) { 10595 var els = []; 10596 for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) { 10597 var query = _a[_i]; 10598 if (typeof query === 'object') { 10599 els.push(query); 10600 } 10601 else { 10602 els.push.apply(els, Array.prototype.slice.call(getElRoot(scrollStartEl).querySelectorAll(query))); 10603 } 10604 } 10605 return els; 10606 }; 10607 return AutoScroller; 10608 }()); 10609 10610 /* 10611 Monitors dragging on an element. Has a number of high-level features: 10612 - minimum distance required before dragging 10613 - minimum wait time ("delay") before dragging 10614 - a mirror element that follows the pointer 10615 */ 10616 var FeaturefulElementDragging = /** @class */ (function (_super) { 10617 __extends(FeaturefulElementDragging, _super); 10618 function FeaturefulElementDragging(containerEl, selector) { 10619 var _this = _super.call(this, containerEl) || this; 10620 _this.containerEl = containerEl; 10621 // options that can be directly set by caller 10622 // the caller can also set the PointerDragging's options as well 10623 _this.delay = null; 10624 _this.minDistance = 0; 10625 _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag 10626 _this.mirrorNeedsRevert = false; 10627 _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup 10628 _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation 10629 _this.isDelayEnded = false; 10630 _this.isDistanceSurpassed = false; 10631 _this.delayTimeoutId = null; 10632 _this.onPointerDown = function (ev) { 10633 if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going 10634 _this.isInteracting = true; 10635 _this.isDelayEnded = false; 10636 _this.isDistanceSurpassed = false; 10637 preventSelection(document.body); 10638 preventContextMenu(document.body); 10639 // prevent links from being visited if there's an eventual drag. 10640 // also prevents selection in older browsers (maybe?). 10641 // not necessary for touch, besides, browser would complain about passiveness. 10642 if (!ev.isTouch) { 10643 ev.origEvent.preventDefault(); 10644 } 10645 _this.emitter.trigger('pointerdown', ev); 10646 if (_this.isInteracting && // not destroyed via pointerdown handler 10647 !_this.pointer.shouldIgnoreMove) { 10648 // actions related to initiating dragstart+dragmove+dragend... 10649 _this.mirror.setIsVisible(false); // reset. caller must set-visible 10650 _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down 10651 _this.startDelay(ev); 10652 if (!_this.minDistance) { 10653 _this.handleDistanceSurpassed(ev); 10654 } 10655 } 10656 } 10657 }; 10658 _this.onPointerMove = function (ev) { 10659 if (_this.isInteracting) { 10660 _this.emitter.trigger('pointermove', ev); 10661 if (!_this.isDistanceSurpassed) { 10662 var minDistance = _this.minDistance; 10663 var distanceSq = void 0; // current distance from the origin, squared 10664 var deltaX = ev.deltaX, deltaY = ev.deltaY; 10665 distanceSq = deltaX * deltaX + deltaY * deltaY; 10666 if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem 10667
10667 _this.handleDistanceSurpassed(ev); 10668 } 10669 } 10670 if (_this.isDragging) { 10671 // a real pointer move? (not one simulated by scrolling) 10672 if (ev.origEvent.type !== 'scroll') { 10673 _this.mirror.handleMove(ev.pageX, ev.pageY); 10674 _this.autoScroller.handleMove(ev.pageX, ev.pageY); 10675 } 10676 _this.emitter.trigger('dragmove', ev); 10677 } 10678 } 10679 }; 10680 _this.onPointerUp = function (ev) { 10681 if (_this.isInteracting) { 10682 _this.isInteracting = false; 10683 allowSelection(document.body); 10684 allowContextMenu(document.body); 10685 _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert 10686 if (_this.isDragging) { 10687 _this.autoScroller.stop(); 10688 _this.tryStopDrag(ev); // which will stop the mirror 10689 } 10690 if (_this.delayTimeoutId) { 10691 clearTimeout(_this.delayTimeoutId); 10692 _this.delayTimeoutId = null; 10693 } 10694 } 10695 }; 10696 var pointer = _this.pointer = new PointerDragging(containerEl); 10697 pointer.emitter.on('pointerdown', _this.onPointerDown); 10698 pointer.emitter.on('pointermove', _this.onPointerMove); 10699 pointer.emitter.on('pointerup', _this.onPointerUp); 10700 if (selector) { 10701 pointer.selector = selector; 10702 } 10703 _this.mirror = new ElementMirror(); 10704 _this.autoScroller = new AutoScroller(); 10705 return _this; 10706 } 10707 FeaturefulElementDragging.prototype.destroy = function () { 10708 this.pointer.destroy(); 10709 // HACK: simulate a pointer-up to end the current drag
10710 // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire) 10711 this.onPointerUp({}); 10712 }; 10713 FeaturefulElementDragging.prototype.startDelay = function (ev) { 10714 var _this = this; 10715 if (typeof this.delay === 'number') { 10716 this.delayTimeoutId = setTimeout(function () { 10717 _this.delayTimeoutId = null; 10718 _this.handleDelayEnd(ev); 10719 }, this.delay); // not assignable to number! 10720 } 10721 else { 10722 this.handleDelayEnd(ev); 10723 } 10724 }; 10725 FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) { 10726 this.isDelayEnded = true; 10727 this.tryStartDrag(ev); 10728 }; 10729 FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) { 10730 this.isDistanceSurpassed = true; 10731 this.tryStartDrag(ev); 10732 }; 10733 FeaturefulElementDragging.prototype.tryStartDrag = function (ev) { 10734 if (this.isDelayEnded && this.isDistanceSurpassed) { 10735 if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) { 10736 this.isDragging = true; 10737 this.mirrorNeedsRevert = false; 10738 this.autoScroller.start(ev.pageX, ev.pageY, this.containerEl); 10739 this.emitter.trigger('dragstart', ev); 10740 if (this.touchScrollAllowed === false) { 10741 this.pointer.cancelTouchScroll(); 10742 } 10743 } 10744 } 10745 }; 10746 FeaturefulElementDragging.prototype.tryStopDrag = function (ev) { 10747 // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events 10748 // that come from the document to fire beforehand. much more convenient this way. 10749 this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev)); 10750 }; 10751 FeaturefulElementDragging.prototype.stopDrag = function (ev) { 10752 this.isDragging = false; 10753 this.emitter.trigger('dragend', ev); 10754 }; 10755 // fill in the implementations... 10756 FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) { 10757 this.pointer.shouldIgnoreMove = bool; 10758 }; 10759 FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) { 10760 this.mirror.setIsVisible(bool); 10761 }; 10762 FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 10763 this.mirrorNeedsRevert = bool; 10764 }; 10765 FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) { 10766 this.autoScroller.isEnabled = bool; 10767 }; 10768 return FeaturefulElementDragging; 10769 }(ElementDragging)); 10770 10771 /* 10772 When this class is instantiated, it records the offset of an element (relative to the document topleft), 10773 and continues to monitor scrolling, updating the cached coordinates if it needs to. 10774 Does not access the DOM after instantiation, so highly performant. 10775 10776 Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element 10777 and an determine if a given point is inside the combined clipping rectangle. 10778 */ 10779 var OffsetTracker = /** @class */ (function () { 10780 function OffsetTracker(el) { 10781 this.origRect = computeRect(el); 10782 // will work fine for divs that have overflow:hidden 10783 this.scrollCaches = getClippingParents(el).map(function (scrollEl) { return new ElementScrollGeomCache(scrollEl, true); }); 10784 } 10785 OffsetTracker.prototype.destroy = function () { 10786 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10787 var scrollCache = _a[_i]; 10788 scrollCache.destroy(); 10789 } 10790 }; 10791 OffsetTracker.prototype.computeLeft = function () { 10792 var left = this.origRect.left; 10793 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10794 var scrollCache = _a[_i]; 10795 left += scrollCache.origScrollLeft - scrollCache.getScrollLeft(); 10796 } 10797 return left; 10798 }; 10799 OffsetTracker.prototype.computeTop = function () { 10800 var top = this.origRect.top; 10801 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10802 var scrollCache = _a[_i]; 10803 top += scrollCache.origScrollTop - scrollCache.getScrollTop(); 10804 } 10805 return top; 10806 }; 10807 OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) { 10808 var point = { left: pageX, top: pageY }; 10809 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10810 var scrollCache = _a[_i];
10811 if (!isIgnoredClipping(scrollCache.getEventTarget()) && 10812 !pointInsideRect(point, scrollCache.clientRect)) { 10813 return false; 10814 } 10815 } 10816 return true; 10817 }; 10818 return OffsetTracker; 10819 }()); 10820 // certain clipping containers should never constrain interactions, like <html> and <body> 10821 // https://github.com/fullcalendar/fullcalendar/issues/3615 10822 function isIgnoredClipping(node) { 10823 var tagName = node.tagName; 10824 return tagName === 'HTML' || tagName === 'BODY'; 10825 } 10826 10827 /* 10828 Tracks movement over multiple droppable areas (aka "hits") 10829 that exist in one or more DateComponents. 10830 Relies on an existing draggable. 10831 10832 emits: 10833 - pointerdown 10834 - dragstart 10835 - hitchange - fires initially, even if not over a hit 10836 - pointerup 10837 - (hitchange - again, to null, if ended over a hit) 10838 - dragend 10839 */ 10840 var HitDragging = /** @class */ (function () { 10841 function HitDragging(dragging, droppableStore) { 10842 var _this = this; 10843 // options that can be set by caller 10844 this.useSubjectCenter = false; 10845 this.requireInitial = true; // if doesn't start out on a hit, won't emit any events 10846 this.initialHit = null; 10847 this.movingHit = null; 10848 this.finalHit = null; // won't ever be populated if shouldIgnoreMove 10849 this.handlePointerDown = function (ev) { 10850 var dragging = _this.dragging; 10851 _this.initialHit = null; 10852 _this.movingHit = null; 10853 _this.finalHit = null; 10854 _this.prepareHits(); 10855 _this.processFirstCoord(ev); 10856 if (_this.initialHit || !_this.requireInitial) { 10857 dragging.setIgnoreMove(false);
10858 // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :( 10859 _this.emitter.trigger('pointerdown', ev); 10860 } 10861 else { 10862 dragging.setIgnoreMove(true); 10863 } 10864 }; 10865 this.handleDragStart = function (ev) { 10866 _this.emitter.trigger('dragstart', ev); 10867 _this.handleMove(ev, true); // force = fire even if initially null 10868 }; 10869 this.handleDragMove = function (ev) { 10870 _this.emitter.trigger('dragmove', ev); 10871 _this.handleMove(ev); 10872 }; 10873 this.handlePointerUp = function (ev) { 10874 _this.releaseHits(); 10875 _this.emitter.trigger('pointerup', ev); 10876 }; 10877 this.handleDragEnd = function (ev) { 10878 if (_this.movingHit) { 10879 _this.emitter.trigger('hitupdate', null, true, ev); 10880 } 10881 _this.finalHit = _this.movingHit; 10882 _this.movingHit = null; 10883 _this.emitter.trigger('dragend', ev); 10884 }; 10885 this.droppableStore = droppableStore; 10886 dragging.emitter.on('pointerdown', this.handlePointerDown); 10887 dragging.emitter.on('dragstart', this.handleDragStart); 10888 dragging.emitter.on('dragmove', this.handleDragMove); 10889 dragging.emitter.on('pointerup', this.handlePointerUp); 10890 dragging.emitter.on('dragend', this.handleDragEnd); 10891 this.dragging = dragging; 10892 this.emitter = new Emitter(); 10893 } 10894 // sets initialHit 10895 // sets coordAdjust 10896 HitDragging.prototype.processFirstCoord = function (ev) { 10897 var origPoint = { left: ev.pageX, top: ev.pageY }; 10898 var adjustedPoint = origPoint; 10899 var subjectEl = ev.subjectEl; 10900 var subjectRect; 10901 if (subjectEl instanceof HTMLElement) { // i.e. not a Document/ShadowRoot 10902 subjectRect = computeRect(subjectEl); 10903 adjustedPoint = constrainPoint(adjustedPoint, subjectRect); 10904 } 10905 var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top); 10906 if (initialHit) { 10907 if (this.useSubjectCenter && subjectRect) { 10908 var slicedSubjectRect = intersectRects(subjectRect, initialHit.rect); 10909 if (slicedSubjectRect) { 10910 adjustedPoint = getRectCenter(slicedSubjectRect); 10911 } 10912 } 10913 this.coordAdjust = diffPoints(adjustedPoint, origPoint); 10914 } 10915 else { 10916 this.coordAdjust = { left: 0, top: 0 }; 10917 } 10918 }; 10919 HitDragging.prototype.handleMove = function (ev, forceHandle) { 10920 var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top); 10921 if (forceHandle || !isHitsEqual(this.movingHit, hit)) { 10922 this.movingHit = hit; 10923 this.emitter.trigger('hitupdate', hit, false, ev); 10924 } 10925 }; 10926 HitDragging.prototype.prepareHits = function () { 10927 this.offsetTrackers = mapHash(this.droppableStore, function (interactionSettings) { 10928 interactionSettings.component.prepareHits(); 10929 return new OffsetTracker(interactionSettings.el); 10930 }); 10931 }; 10932 HitDragging.prototype.releaseHits = function () { 10933 var offsetTrackers = this.offsetTrackers; 10934 for (var id in offsetTrackers) { 10935 offsetTrackers[id].destroy(); 10936 } 10937 this.offsetTrackers = {}; 10938 }; 10939 HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) { 10940 var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers; 10941 var bestHit = null; 10942 for (var id in droppableStore) { 10943 var component = droppableStore[id].component; 10944 var offsetTracker = offsetTrackers[id]; 10945 if (offsetTracker && // wasn't destroyed mid-drag 10946 offsetTracker.isWithinClipping(offsetLeft, offsetTop)) { 10947 var originLeft = offsetTracker.computeLeft(); 10948 var originTop = offsetTracker.computeTop(); 10949 var positionLeft = offsetLeft - originLeft; 10950 var positionTop = offsetTop - originTop; 10951 var origRect = offsetTracker.origRect; 10952 var width = origRect.right - origRect.left; 10953 var height = origRect.bottom - origRect.top; 10954 if ( 10955 // must be within the element's bounds 10956 positionLeft >= 0 && positionLeft < width && 10957 positionTop >= 0 && positionTop < height) { 10958 var hit = component.queryHit(positionLeft, positionTop, width, height); 10959 if (hit && ( 10960 // make sure the hit is within activeRange, meaning it's not a dead cell 10961 rangeContainsRange(hit.dateProfile.activeRange, hit.dateSpan.range)) && 10962 (!bestHit || hit.layer > bestHit.layer)) { 10963 hit.componentId = id; 10964 hit.context = component.context; 10965 // TODO: better way to re-orient rectangle 10966 hit.rect.left += originLeft; 10967 hit.rect.right += originLeft; 10968 hit.rect.top += originTop; 10969 hit.rect.bottom += originTop; 10970 bestHit = hit; 10971 } 10972 } 10973 } 10974 } 10975 return bestHit; 10976 }; 10977 return HitDragging; 10978 }()); 10979 function isHitsEqual(hit0, hit1) { 10980 if (!hit0 && !hit1) { 10981 return true; 10982 } 10983 if (Boolean(hit0) !== Boolean(hit1)) { 10984 return false; 10985 } 10986 return isDateSpansEqual(hit0.dateSpan, hit1.dateSpan); 10987 } 10988 10989 function buildDatePointApiWithContext(dateSpan, context) { 10990 var props = {}; 10991 for (var _i = 0, _a = context.pluginHooks.datePointTransforms; _i < _a.length; _i++) { 10992 var transform = _a[_i]; 10993 __assign(props, transform(dateSpan, context)); 10994 } 10995 __assign(props, buildDatePointApi(dateSpan, context.dateEnv)); 10996 return props; 10997 } 10998 function buildDatePointApi(span, dateEnv) { 10999 return {
11000 date: dateEnv.toDate(span.range.start), 11001 dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }), 11002 allDay: span.allDay, 11003 }; 11004 } 11005 11006 /* 11007 Monitors when the user clicks on a specific date/time of a component. 11008 A pointerdown+pointerup on the same "hit" constitutes a click. 11009 */ 11010 var DateClicking = /** @class */ (function (_super) { 11011 __extends(DateClicking, _super); 11012 function DateClicking(settings) { 11013 var _this = _super.call(this, settings) || this; 11014 _this.handlePointerDown = function (pev) { 11015 var dragging = _this.dragging; 11016 var downEl = pev.origEvent.target; 11017 // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired 11018 dragging.setIgnoreMove(!_this.component.isValidDateDownEl(downEl)); 11019 }; 11020 // won't even fire if moving was ignored 11021 _this.handleDragEnd = function (ev) { 11022 var component = _this.component; 11023 var pointer = _this.dragging.pointer; 11024 if (!pointer.wasTouchScroll) { 11025 var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit; 11026 if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) { 11027 var context = component.context; 11028 var arg = __assign(__assign({}, buildDatePointApiWithContext(initialHit.dateSpan, context)), { dayEl: initialHit.dayEl, jsEvent: ev.origEvent, view: context.viewApi || context.calendarApi.view }); 11029 context.emitter.trigger('dateClick', arg); 11030 } 11031 } 11032 }; 11033 // we DO want to watch pointer moves because otherwise finalHit won't get populated 11034 _this.dragging = new FeaturefulElementDragging(settings.el); 11035 _this.dragging.autoScroller.isEnabled = false; 11036 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 11037 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11038 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11039 return _this; 11040 } 11041 DateClicking.prototype.destroy = function () { 11042 this.dragging.destroy(); 11043 }; 11044 return DateClicking; 11045 }(Interaction)); 11046 11047 /* 11048 Tracks when the user selects a portion of time of a component, 11049 constituted by a drag over date cells, with a possible delay at the beginning of the drag. 11050 */ 11051 var DateSelecting = /** @class */ (function (_super) { 11052 __extends(DateSelecting, _super); 11053 function DateSelecting(settings) { 11054 var _this = _super.call(this, settings) || this; 11055 _this.dragSelection = null; 11056 _this.handlePointerDown = function (ev) { 11057 var _a = _this, component = _a.component, dragging = _a.dragging; 11058 var options = component.context.options; 11059 var canSelect = options.selectable && 11060 component.isValidDateDownEl(ev.origEvent.target); 11061 // don't bother to watch expensive moves if component won't do selection 11062 dragging.setIgnoreMove(!canSelect); 11063 // if touch, require user to hold down 11064 dragging.delay = ev.isTouch ? getComponentTouchDelay$1(component) : null; 11065 }; 11066 _this.handleDragStart = function (ev) { 11067 _this.component.context.calendarApi.unselect(ev); // unselect previous selections 11068 }; 11069 _this.handleHitUpdate = function (hit, isFinal) { 11070 var context = _this.component.context; 11071 var dragSelection = null; 11072 var isInvalid = false; 11073 if (hit) { 11074 var initialHit = _this.hitDragging.initialHit; 11075 var disallowed = hit.componentId === initialHit.componentId 11076 && _this.isHitComboAllowed 11077 && !_this.isHitComboAllowed(initialHit, hit); 11078 if (!disallowed) { 11079 dragSelection = joinHitsIntoSelection(initialHit, hit, context.pluginHooks.dateSelectionTransformers); 11080 } 11081 if (!dragSelection || !isDateSelectionValid(dragSelection, hit.dateProfile, context)) { 11082 isInvalid = true; 11083 dragSelection = null; 11084 } 11085 } 11086 if (dragSelection) { 11087 context.dispatch({ type: 'SELECT_DATES', selection: dragSelection }); 11088 } 11089 else if (!isFinal) { // only unselect if moved away while dragging 11090 context.dispatch({ type: 'UNSELECT_DATES' }); 11091 } 11092 if (!isInvalid) {
11093 enableCursor(); 11094 } 11095 else { 11096 disableCursor(); 11097 } 11098 if (!isFinal) { 11099 _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging 11100 } 11101 }; 11102 _this.handlePointerUp = function (pev) { 11103 if (_this.dragSelection) { 11104 // selection is already rendered, so just need to report selection 11105 triggerDateSelect(_this.dragSelection, pev, _this.component.context); 11106 _this.dragSelection = null; 11107 } 11108 }; 11109 var component = settings.component; 11110 var options = component.context.options; 11111 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 11112 dragging.touchScrollAllowed = false; 11113 dragging.minDistance = options.selectMinDistance || 0; 11114 dragging.autoScroller.isEnabled = options.dragScroll; 11115 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 11116 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11117 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11118 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11119 hitDragging.emitter.on('pointerup', _this.handlePointerUp); 11120 return _this; 11121 } 11122 DateSelecting.prototype.destroy = function () { 11123 this.dragging.destroy(); 11124 }; 11125 return DateSelecting; 11126 }(Interaction)); 11127 function getComponentTouchDelay$1(component) { 11128 var options = component.context.options; 11129 var delay = options.selectLongPressDelay; 11130 if (delay == null) { 11131 delay = options.longPressDelay; 11132 } 11133 return delay; 11134 } 11135 function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) { 11136 var dateSpan0 = hit0.dateSpan; 11137 var dateSpan1 = hit1.dateSpan; 11138 var ms = [ 11139 dateSpan0.range.start, 11140 dateSpan0.range.end, 11141 dateSpan1.range.start, 11142 dateSpan1.range.end, 11143 ]; 11144 ms.sort(compareNumbers); 11145 var props = {}; 11146 for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) { 11147 var transformer = dateSelectionTransformers_1[_i]; 11148 var res = transformer(hit0, hit1); 11149 if (res === false) { 11150 return null; 11151 } 11152 if (res) { 11153 __assign(props, res); 11154 } 11155 } 11156 props.range = { start: ms[0], end: ms[3] }; 11157 props.allDay = dateSpan0.allDay; 11158 return props; 11159 } 11160 11161 var EventDragging = /** @class */ (function (_super) { 11162 __extends(EventDragging, _super); 11163 function EventDragging(settings) { 11164 var _this = _super.call(this, settings) || this; 11165 // internal state 11166 _this.subjectEl = null; 11167 _this.subjectSeg = null; // the seg being selected/dragged 11168 _this.isDragging = false; 11169 _this.eventRange = null; 11170 _this.relevantEvents = null; // the events being dragged 11171 _this.receivingContext = null; 11172 _this.validMutation = null; 11173 _this.mutatedRelevantEvents = null; 11174 _this.handlePointerDown = function (ev) { 11175 var origTarget = ev.origEvent.target; 11176 var _a = _this, component = _a.component, dragging = _a.dragging; 11177 var mirror = dragging.mirror; 11178 var options = component.context.options; 11179 var initialContext = component.context; 11180 _this.subjectEl = ev.subjectEl; 11181 var subjectSeg = _this.subjectSeg = getElSeg(ev.subjectEl); 11182 var eventRange = _this.eventRange = subjectSeg.eventRange; 11183 var eventInstanceId = eventRange.instance.instanceId; 11184 _this.relevantEvents = getRelevantEvents(initialContext.getCurrentData().eventStore, eventInstanceId); 11185 dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance; 11186 dragging.delay = 11187 // only do a touch delay if touch and this event hasn't been selected yet 11188 (ev.isTouch && eventInstanceId !== component.props.eventSelection) ? 11189 getComponentTouchDelay(component) : 11190 null; 11191 if (options.fixedMirrorParent) { 11192 mirror.parentNode = options.fixedMirrorParent; 11193 } 11194 else { 11195 mirror.parentNode = elementClosest(origTarget, '.fc'); 11196 } 11197 mirror.revertDuration = options.dragRevertDuration; 11198 var isValid = component.isValidSegDownEl(origTarget) && 11199 !elementClosest(origTarget, '.fc-event-resizer'); // NOT on a resizer 11200 dragging.setIgnoreMove(!isValid); 11201 // disable dragging for elements that are resizable (ie, selectable) 11202 // but are not draggable 11203 _this.isDragging = isValid && 11204 ev.subjectEl.classList.contains('fc-event-draggable'); 11205 }; 11206 _this.handleDragStart = function (ev) { 11207 var initialContext = _this.component.context; 11208 var eventRange = _this.eventRange; 11209 var eventInstanceId = eventRange.instance.instanceId; 11210 if (ev.isTouch) { 11211 // need to select a different event? 11212 if (eventInstanceId !== _this.component.props.eventSelection) { 11213 initialContext.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId }); 11214 } 11215 } 11216 else { 11217 // if now using mouse, but was previous touch interaction, clear selected event 11218 initialContext.dispatch({ type: 'UNSELECT_EVENT' }); 11219 } 11220 if (_this.isDragging) { 11221 initialContext.calendarApi.unselect(ev); // unselect *date* selection 11222 initialContext.emitter.trigger('eventDragStart', { 11223 el: _this.subjectEl, 11224 event: new EventApi(initialContext, eventRange.def, eventRange.instance), 11225 jsEvent: ev.origEvent, 11226 view: initialContext.viewApi, 11227 }); 11228 } 11229 }; 11230 _this.handleHitUpdate = function (hit, isFinal) { 11231 if (!_this.isDragging) { 11232 return; 11233 } 11234 var relevantEvents = _this.relevantEvents; 11235 var initialHit = _this.hitDragging.initialHit; 11236 var initialContext = _this.component.context; 11237 // states based on new hit 11238 var receivingContext = null; 11239 var mutation = null; 11240 var mutatedRelevantEvents = null; 11241 var isInvalid = false; 11242 var interaction = { 11243 affectedEvents: relevantEvents, 11244 mutatedEvents: createEmptyEventStore(), 11245 isEvent: true, 11246 }; 11247 if (hit) { 11248 receivingContext = hit.context; 11249 var receivingOptions = receivingContext.options; 11250 if (initialContext === receivingContext || 11251 (receivingOptions.editable && receivingOptions.droppable)) { 11252 mutation = computeEventMutation(initialHit, hit, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers); 11253 if (mutation) { 11254 mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, receivingContext.getCurrentData().eventUiBases, mutation, receivingContext); 11255 interaction.mutatedEvents = mutatedRelevantEvents; 11256 if (!isInteractionValid(interaction, hit.dateProfile, receivingContext)) { 11257 isInvalid = true; 11258 mutation = null; 11259 mutatedRelevantEvents = null; 11260 interaction.mutatedEvents = createEmptyEventStore(); 11261 } 11262 } 11263 } 11264 else { 11265 receivingContext = null; 11266 } 11267 } 11268 _this.displayDrag(receivingContext, interaction); 11269 if (!isInvalid) {
11270 enableCursor(); 11271 } 11272 else { 11273 disableCursor(); 11274 } 11275 if (!isFinal) { 11276 if (initialContext === receivingContext && // TODO: write test for this 11277 isHitsEqual(initialHit, hit)) { 11278 mutation = null; 11279 } 11280 _this.dragging.setMirrorNeedsRevert(!mutation); 11281 // render the mirror if no already-rendered mirror 11282 // TODO: wish we could somehow wait for dispatch to guarantee render 11283 _this.dragging.setMirrorIsVisible(!hit || !getElRoot(_this.subjectEl).querySelector('.fc-event-mirror')); 11284 // assign states based on new hit 11285 _this.receivingContext = receivingContext; 11286 _this.validMutation = mutation; 11287 _this.mutatedRelevantEvents = mutatedRelevantEvents; 11288 } 11289 }; 11290 _this.handlePointerUp = function () { 11291 if (!_this.isDragging) { 11292 _this.cleanup(); // because handleDragEnd won't fire 11293 } 11294 }; 11295 _this.handleDragEnd = function (ev) { 11296 if (_this.isDragging) { 11297 var initialContext_1 = _this.component.context; 11298 var initialView = initialContext_1.viewApi; 11299 var _a = _this, receivingContext_1 = _a.receivingContext, validMutation = _a.validMutation; 11300 var eventDef = _this.eventRange.def; 11301 var eventInstance = _this.eventRange.instance; 11302 var eventApi = new EventApi(initialContext_1, eventDef, eventInstance); 11303 var relevantEvents_1 = _this.relevantEvents; 11304 var mutatedRelevantEvents_1 = _this.mutatedRelevantEvents; 11305 var finalHit = _this.hitDragging.finalHit; 11306 _this.clearDrag(); // must happen after revert animation 11307 initialContext_1.emitter.trigger('eventDragStop', { 11308 el: _this.subjectEl, 11309 event: eventApi, 11310 jsEvent: ev.origEvent, 11311 view: initialView, 11312 }); 11313 if (validMutation) { 11314 // dropped within same calendar 11315 if (receivingContext_1 === initialContext_1) { 11316 var updatedEventApi = new EventApi(initialContext_1, mutatedRelevantEvents_1.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents_1.instances[eventInstance.instanceId] : null); 11317 initialContext_1.dispatch({ 11318 type: 'MERGE_EVENTS', 11319 eventStore: mutatedRelevantEvents_1, 11320 }); 11321 var eventChangeArg = { 11322 oldEvent: eventApi, 11323 event: updatedEventApi, 11324 relatedEvents: buildEventApis(mutatedRelevantEvents_1, initialContext_1, eventInstance), 11325 revert: function () { 11326 initialContext_1.dispatch({ 11327 type: 'MERGE_EVENTS', 11328 eventStore: relevantEvents_1, // the pre-change data 11329 }); 11330 }, 11331 }; 11332 var transformed = {}; 11333 for (var _i = 0, _b = initialContext_1.getCurrentData().pluginHooks.eventDropTransformers; _i < _b.length; _i++) { 11334 var transformer = _b[_i]; 11335 __assign(transformed, transformer(validMutation, initialContext_1)); 11336 } 11337 initialContext_1.emitter.trigger('eventDrop', __assign(__assign(__assign({}, eventChangeArg), transformed), { el: ev.subjectEl, delta: validMutation.datesDelta, jsEvent: ev.origEvent, view: initialView })); 11338 initialContext_1.emitter.trigger('eventChange', eventChangeArg); 11339 // dropped in different calendar 11340 } 11341 else if (receivingContext_1) { 11342 var eventRemoveArg = { 11343 event: eventApi, 11344 relatedEvents: buildEventApis(relevantEvents_1, initialContext_1, eventInstance), 11345 revert: function () { 11346 initialContext_1.dispatch({ 11347 type: 'MERGE_EVENTS', 11348 eventStore: relevantEvents_1, 11349 }); 11350 }, 11351 }; 11352 initialContext_1.emitter.trigger('eventLeave', __assign(__assign({}, eventRemoveArg), { draggedEl: ev.subjectEl, view: initialView })); 11353 initialContext_1.dispatch({
11354 type: 'REMOVE_EVENTS', 11355 eventStore: relevantEvents_1, 11356 }); 11357 initialContext_1.emitter.trigger('eventRemove', eventRemoveArg); 11358 var addedEventDef = mutatedRelevantEvents_1.defs[eventDef.defId]; 11359 var addedEventInstance = mutatedRelevantEvents_1.instances[eventInstance.instanceId]; 11360 var addedEventApi = new EventApi(receivingContext_1, addedEventDef, addedEventInstance); 11361 receivingContext_1.dispatch({ 11362 type: 'MERGE_EVENTS', 11363 eventStore: mutatedRelevantEvents_1, 11364 }); 11365 var eventAddArg = { 11366 event: addedEventApi, 11367 relatedEvents: buildEventApis(mutatedRelevantEvents_1, receivingContext_1, addedEventInstance), 11368 revert: function () { 11369 receivingContext_1.dispatch({ 11370 type: 'REMOVE_EVENTS', 11371 eventStore: mutatedRelevantEvents_1, 11372 }); 11373 }, 11374 }; 11375 receivingContext_1.emitter.trigger('eventAdd', eventAddArg); 11376 if (ev.isTouch) { 11377 receivingContext_1.dispatch({ 11378 type: 'SELECT_EVENT', 11379 eventInstanceId: eventInstance.instanceId, 11380 }); 11381 } 11382 receivingContext_1.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext_1)), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.context.viewApi })); 11383 receivingContext_1.emitter.trigger('eventReceive', __assign(__assign({}, eventAddArg), { draggedEl: ev.subjectEl, view: finalHit.context.viewApi })); 11384 } 11385 } 11386 else { 11387 initialContext_1.emitter.trigger('_noEventDrop'); 11388 } 11389 } 11390 _this.cleanup(); 11391 }; 11392 var component = _this.component; 11393 var options = component.context.options; 11394 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 11395 dragging.pointer.selector = EventDragging.SELECTOR; 11396 dragging.touchScrollAllowed = false; 11397 dragging.autoScroller.isEnabled = options.dragScroll; 11398 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsStore); 11399 hitDragging.useSubjectCenter = settings.useEventCenter; 11400 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11401 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11402 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11403 hitDragging.emitter.on('pointerup', _this.handlePointerUp); 11404 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11405 return _this; 11406 } 11407 EventDragging.prototype.destroy = function () { 11408 this.dragging.destroy(); 11409 }; 11410 // render a drag state on the next receivingCalendar 11411 EventDragging.prototype.displayDrag = function (nextContext, state) { 11412 var initialContext = this.component.context; 11413 var prevContext = this.receivingContext; 11414 // does the previous calendar need to be cleared? 11415 if (prevContext && prevContext !== nextContext) { 11416 // does the initial calendar need to be cleared? 11417 // if so, don't clear all the way. we still need to to hide the affectedEvents 11418 if (prevContext === initialContext) { 11419 prevContext.dispatch({ 11420 type: 'SET_EVENT_DRAG', 11421 state: { 11422 affectedEvents: state.affectedEvents, 11423 mutatedEvents: createEmptyEventStore(), 11424 isEvent: true, 11425 }, 11426 }); 11427 // completely clear the old calendar if it wasn't the initial 11428 } 11429 else { 11430 prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11431 } 11432 } 11433 if (nextContext) { 11434 nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state }); 11435 } 11436 }; 11437 EventDragging.prototype.clearDrag = function () { 11438 var initialCalendar = this.component.context; 11439 var receivingContext = this.receivingContext; 11440 if (receivingContext) { 11441 receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11442 } 11443 // the initial calendar might have an dummy drag state from displayDrag 11444 if (initialCalendar !== receivingContext) { 11445 initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11446 } 11447 }; 11448 EventDragging.prototype.cleanup = function () { 11449 this.subjectSeg = null; 11450 this.isDragging = false; 11451 this.eventRange = null; 11452 this.relevantEvents = null; 11453 this.receivingContext = null; 11454 this.validMutation = null; 11455 this.mutatedRelevantEvents = null; 11456 }; 11457 // TODO: test this in IE11 11458 // QUESTION: why do we need it on the resizable??? 11459 EventDragging.SELECTOR = '.fc-event-draggable, .fc-event-resizable'; 11460 return EventDragging; 11461 }(Interaction)); 11462 function computeEventMutation(hit0, hit1, massagers) { 11463 var dateSpan0 = hit0.dateSpan; 11464 var dateSpan1 = hit1.dateSpan; 11465 var date0 = dateSpan0.range.start; 11466 var date1 = dateSpan1.range.start; 11467 var standardProps = {}; 11468 if (dateSpan0.allDay !== dateSpan1.allDay) { 11469 standardProps.allDay = dateSpan1.allDay; 11470 standardProps.hasEnd = hit1.context.options.allDayMaintainDuration; 11471 if (dateSpan1.allDay) { 11472 // means date1 is already start-of-day, 11473 // but date0 needs to be converted 11474 date0 = startOfDay(date0); 11475 } 11476 } 11477 var delta = diffDates(date0, date1, hit0.context.dateEnv, hit0.componentId === hit1.componentId ? 11478 hit0.largeUnit : 11479 null); 11480 if (delta.milliseconds) { // has hours/minutes/seconds 11481 standardProps.allDay = false; 11482 } 11483 var mutation = { 11484 datesDelta: delta, 11485 standardProps: standardProps, 11486 }; 11487 for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) { 11488 var massager = massagers_1[_i]; 11489 massager(mutation, hit0, hit1); 11490 } 11491 return mutation; 11492 } 11493 function getComponentTouchDelay(component) { 11494 var options = component.context.options;
11495 var delay = options.eventLongPressDelay; 11496 if (delay == null) { 11497 delay = options.longPressDelay; 11498 } 11499 return delay; 11500 } 11501 11502 var EventResizing = /** @class */ (function (_super) { 11503 __extends(EventResizing, _super); 11504 function EventResizing(settings) { 11505 var _this = _super.call(this, settings) || this; 11506 // internal state 11507 _this.draggingSegEl = null; 11508 _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg? 11509 _this.eventRange = null; 11510 _this.relevantEvents = null; 11511 _this.validMutation = null; 11512 _this.mutatedRelevantEvents = null; 11513 _this.handlePointerDown = function (ev) { 11514 var component = _this.component; 11515 var segEl = _this.querySegEl(ev); 11516 var seg = getElSeg(segEl); 11517 var eventRange = _this.eventRange = seg.eventRange; 11518 _this.dragging.minDistance = component.context.options.eventDragMinDistance; 11519 // if touch, need to be working with a selected event 11520 _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) || 11521 (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId)); 11522 }; 11523 _this.handleDragStart = function (ev) { 11524 var context = _this.component.context; 11525 var eventRange = _this.eventRange; 11526 _this.relevantEvents = getRelevantEvents(context.getCurrentData().eventStore, _this.eventRange.instance.instanceId); 11527 var segEl = _this.querySegEl(ev); 11528 _this.draggingSegEl = segEl; 11529 _this.draggingSeg = getElSeg(segEl); 11530 context.calendarApi.unselect(); 11531 context.emitter.trigger('eventResizeStart', { 11532 el: segEl, 11533 event: new EventApi(context, eventRange.def, eventRange.instance), 11534 jsEvent: ev.origEvent, 11535 view: context.viewApi, 11536 }); 11537 }; 11538 _this.handleHitUpdate = function (hit, isFinal, ev) { 11539 var context = _this.component.context; 11540 var relevantEvents = _this.relevantEvents; 11541 var initialHit = _this.hitDragging.initialHit; 11542 var eventInstance = _this.eventRange.instance; 11543 var mutation = null; 11544 var mutatedRelevantEvents = null; 11545 var isInvalid = false; 11546 var interaction = { 11547 affectedEvents: relevantEvents, 11548 mutatedEvents: createEmptyEventStore(), 11549 isEvent: true, 11550 }; 11551 if (hit) { 11552 var disallowed = hit.componentId === initialHit.componentId 11553 && _this.isHitComboAllowed 11554 && !_this.isHitComboAllowed(initialHit, hit); 11555 if (!disallowed) { 11556 mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-event-resizer-start'), eventInstance.range); 11557 } 11558 } 11559 if (mutation) { 11560 mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, context.getCurrentData().eventUiBases, mutation, context); 11561 interaction.mutatedEvents = mutatedRelevantEvents; 11562 if (!isInteractionValid(interaction, hit.dateProfile, context)) { 11563 isInvalid = true; 11564 mutation = null; 11565 mutatedRelevantEvents = null; 11566 interaction.mutatedEvents = null; 11567 } 11568 } 11569 if (mutatedRelevantEvents) { 11570 context.dispatch({ 11571 type: 'SET_EVENT_RESIZE', 11572 state: interaction, 11573 }); 11574 } 11575 else { 11576 context.dispatch({ type: 'UNSET_EVENT_RESIZE' }); 11577 } 11578 if (!isInvalid) {
11579 enableCursor(); 11580 } 11581 else { 11582 disableCursor(); 11583 } 11584 if (!isFinal) { 11585 if (mutation && isHitsEqual(initialHit, hit)) { 11586 mutation = null; 11587 } 11588 _this.validMutation = mutation; 11589 _this.mutatedRelevantEvents = mutatedRelevantEvents; 11590 } 11591 }; 11592 _this.handleDragEnd = function (ev) { 11593 var context = _this.component.context; 11594 var eventDef = _this.eventRange.def; 11595 var eventInstance = _this.eventRange.instance; 11596 var eventApi = new EventApi(context, eventDef, eventInstance); 11597 var relevantEvents = _this.relevantEvents; 11598 var mutatedRelevantEvents = _this.mutatedRelevantEvents; 11599 context.emitter.trigger('eventResizeStop', { 11600 el: _this.draggingSegEl, 11601 event: eventApi, 11602 jsEvent: ev.origEvent, 11603 view: context.viewApi, 11604 }); 11605 if (_this.validMutation) { 11606 var updatedEventApi = new EventApi(context, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null); 11607 context.dispatch({ 11608 type: 'MERGE_EVENTS', 11609 eventStore: mutatedRelevantEvents, 11610 }); 11611 var eventChangeArg = { 11612 oldEvent: eventApi, 11613 event: updatedEventApi, 11614 relatedEvents: buildEventApis(mutatedRelevantEvents, context, eventInstance), 11615 revert: function () { 11616 context.dispatch({ 11617 type: 'MERGE_EVENTS', 11618 eventStore: relevantEvents, // the pre-change events 11619 }); 11620 }, 11621 }; 11622 context.emitter.trigger('eventResize', __assign(__assign({}, eventChangeArg), { el: _this.draggingSegEl, startDelta: _this.validMutation.startDelta || createDuration(0), endDelta: _this.validMutation.endDelta || createDuration(0), jsEvent: ev.origEvent, view: context.viewApi })); 11623 context.emitter.trigger('eventChange', eventChangeArg); 11624 } 11625 else { 11626 context.emitter.trigger('_noEventResize'); 11627 } 11628 // reset all internal state 11629 _this.draggingSeg = null; 11630 _this.relevantEvents = null; 11631 _this.validMutation = null; 11632 // okay to keep eventInstance around. useful to set it in handlePointerDown 11633 }; 11634 var component = settings.component; 11635 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 11636 dragging.pointer.selector = '.fc-event-resizer'; 11637 dragging.touchScrollAllowed = false; 11638 dragging.autoScroller.isEnabled = component.context.options.dragScroll; 11639 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 11640 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11641 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11642 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11643 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11644 return _this; 11645 } 11646 EventResizing.prototype.destroy = function () { 11647 this.dragging.destroy(); 11648 }; 11649 EventResizing.prototype.querySegEl = function (ev) { 11650 return elementClosest(ev.subjectEl, '.fc-event'); 11651 }; 11652 return EventResizing; 11653 }(Interaction)); 11654 function computeMutation(hit0, hit1, isFromStart, instanceRange) { 11655 var dateEnv = hit0.context.dateEnv; 11656 var date0 = hit0.dateSpan.range.start; 11657 var date1 = hit1.dateSpan.range.start; 11658 var delta = diffDates(date0, date1, dateEnv, hit0.largeUnit); 11659 if (isFromStart) { 11660 if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) { 11661 return { startDelta: delta }; 11662 } 11663 } 11664 else if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) { 11665 return { endDelta: delta }; 11666 } 11667 return null; 11668 } 11669 11670 var UnselectAuto = /** @class */ (function () { 11671 function UnselectAuto(context) { 11672 var _this = this; 11673 this.context = context; 11674 this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system 11675 this.matchesCancel = false; 11676 this.matchesEvent = false; 11677 this.onSelect = function (selectInfo) { 11678 if (selectInfo.jsEvent) { 11679 _this.isRecentPointerDateSelect = true; 11680 } 11681 }; 11682 this.onDocumentPointerDown = function (pev) { 11683 var unselectCancel = _this.context.options.unselectCancel; 11684 var downEl = getEventTargetViaRoot(pev.origEvent); 11685 _this.matchesCancel = !!elementClosest(downEl, unselectCancel); 11686 _this.matchesEvent = !!elementClosest(downEl, EventDragging.SELECTOR); // interaction started on an event? 11687 }; 11688 this.onDocumentPointerUp = function (pev) { 11689 var context = _this.context; 11690 var documentPointer = _this.documentPointer; 11691 var calendarState = context.getCurrentData(); 11692 // touch-scrolling should never unfocus any type of selection 11693 if (!documentPointer.wasTouchScroll) { 11694 if (calendarState.dateSelection && // an existing date selection? 11695 !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp? 11696 ) { 11697 var unselectAuto = context.options.unselectAuto; 11698 if (unselectAuto && (!unselectAuto || !_this.matchesCancel)) { 11699 context.calendarApi.unselect(pev); 11700 } 11701 } 11702 if (calendarState.eventSelection && // an existing event selected? 11703 !_this.matchesEvent // interaction DIDN'T start on an event 11704 ) { 11705 context.dispatch({ type: 'UNSELECT_EVENT' }); 11706 } 11707 } 11708 _this.isRecentPointerDateSelect = false; 11709 }; 11710 var documentPointer = this.documentPointer = new PointerDragging(document); 11711 documentPointer.shouldIgnoreMove = true; 11712 documentPointer.shouldWatchScroll = false; 11713 documentPointer.emitter.on('pointerdown', this.onDocumentPointerDown);
11714 documentPointer.emitter.on('pointerup', this.onDocumentPointerUp); 11715 /* 11716 TODO: better way to know about whether there was a selection with the pointer 11717 */ 11718 context.emitter.on('select', this.onSelect); 11719 } 11720 UnselectAuto.prototype.destroy = function () { 11721 this.context.emitter.off('select', this.onSelect); 11722 this.documentPointer.destroy(); 11723 }; 11724 return UnselectAuto; 11725 }()); 11726 11727 var OPTION_REFINERS$3 = { 11728 fixedMirrorParent: identity, 11729 }; 11730 var LISTENER_REFINERS = { 11731 dateClick: identity, 11732 eventDragStart: identity, 11733 eventDragStop: identity, 11734 eventDrop: identity, 11735 eventResizeStart: identity, 11736 eventResizeStop: identity, 11737 eventResize: identity, 11738 drop: identity, 11739 eventReceive: identity, 11740 eventLeave: identity, 11741 }; 11742 11743 /* 11744 Given an already instantiated draggable object for one-or-more elements, 11745 Interprets any dragging as an attempt to drag an events that lives outside 11746 of a calendar onto a calendar. 11747 */ 11748 var ExternalElementDragging = /** @class */ (function () { 11749 function ExternalElementDragging(dragging, suppliedDragMeta) { 11750 var _this = this; 11751 this.receivingContext = null; 11752 this.droppableEvent = null; // will exist for all drags, even if create:false 11753 this.suppliedDragMeta = null; 11754 this.dragMeta = null; 11755 this.handleDragStart = function (ev) { 11756 _this.dragMeta = _this.buildDragMeta(ev.subjectEl); 11757 }; 11758 this.handleHitUpdate = function (hit, isFinal, ev) { 11759 var dragging = _this.hitDragging.dragging; 11760 var receivingContext = null; 11761 var droppableEvent = null; 11762 var isInvalid = false; 11763 var interaction = { 11764 affectedEvents: createEmptyEventStore(), 11765 mutatedEvents: createEmptyEventStore(), 11766 isEvent: _this.dragMeta.create, 11767 }; 11768 if (hit) { 11769 receivingContext = hit.context; 11770 if (_this.canDropElOnCalendar(ev.subjectEl, receivingContext)) { 11771 droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingContext); 11772 interaction.mutatedEvents = eventTupleToStore(droppableEvent); 11773 isInvalid = !isInteractionValid(interaction, hit.dateProfile, receivingContext); 11774 if (isInvalid) { 11775 interaction.mutatedEvents = createEmptyEventStore(); 11776 droppableEvent = null; 11777 } 11778 } 11779 } 11780 _this.displayDrag(receivingContext, interaction); 11781 // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?) 11782 // TODO: wish we could somehow wait for dispatch to guarantee render 11783 dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-event-mirror')); 11784 if (!isInvalid) { 11785 enableCursor(); 11786 } 11787 else { 11788 disableCursor(); 11789 } 11790 if (!isFinal) { 11791 dragging.setMirrorNeedsRevert(!droppableEvent); 11792 _this.receivingContext = receivingContext; 11793 _this.droppableEvent = droppableEvent; 11794 } 11795 }; 11796 this.handleDragEnd = function (pev) { 11797 var _a = _this, receivingContext = _a.receivingContext, droppableEvent = _a.droppableEvent; 11798 _this.clearDrag(); 11799 if (receivingContext && droppableEvent) { 11800 var finalHit = _this.hitDragging.finalHit; 11801 var finalView = finalHit.context.viewApi; 11802 var dragMeta = _this.dragMeta; 11803 receivingContext.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView })); 11804 if (dragMeta.create) { 11805 var addingEvents_1 = eventTupleToStore(droppableEvent); 11806 receivingContext.dispatch({ 11807 type: 'MERGE_EVENTS', 11808 eventStore: addingEvents_1, 11809 }); 11810 if (pev.isTouch) { 11811 receivingContext.dispatch({ 11812 type: 'SELECT_EVENT', 11813 eventInstanceId: droppableEvent.instance.instanceId, 11814 }); 11815 } 11816 // signal that an external event landed 11817 receivingContext.emitter.trigger('eventReceive', { 11818 event: new EventApi(receivingContext, droppableEvent.def, droppableEvent.instance), 11819 relatedEvents: [], 11820 revert: function () { 11821 receivingContext.dispatch({
11822 type: 'REMOVE_EVENTS', 11823 eventStore: addingEvents_1, 11824 }); 11825 }, 11826 draggedEl: pev.subjectEl, 11827 view: finalView, 11828 }); 11829 } 11830 } 11831 _this.receivingContext = null; 11832 _this.droppableEvent = null; 11833 }; 11834 var hitDragging = this.hitDragging = new HitDragging(dragging, interactionSettingsStore); 11835 hitDragging.requireInitial = false; // will start outside of a component 11836 hitDragging.emitter.on('dragstart', this.handleDragStart); 11837 hitDragging.emitter.on('hitupdate', this.handleHitUpdate); 11838 hitDragging.emitter.on('dragend', this.handleDragEnd); 11839 this.suppliedDragMeta = suppliedDragMeta; 11840 } 11841 ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) { 11842 if (typeof this.suppliedDragMeta === 'object') { 11843 return parseDragMeta(this.suppliedDragMeta); 11844 } 11845 if (typeof this.suppliedDragMeta === 'function') { 11846 return parseDragMeta(this.suppliedDragMeta(subjectEl)); 11847 } 11848 return getDragMetaFromEl(subjectEl); 11849 }; 11850 ExternalElementDragging.prototype.displayDrag = function (nextContext, state) { 11851 var prevContext = this.receivingContext; 11852 if (prevContext && prevContext !== nextContext) { 11853 prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11854 } 11855 if (nextContext) { 11856 nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state }); 11857 } 11858 }; 11859 ExternalElementDragging.prototype.clearDrag = function () { 11860 if (this.receivingContext) { 11861 this.receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11862 } 11863 }; 11864 ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingContext) { 11865 var dropAccept = receivingContext.options.dropAccept; 11866 if (typeof dropAccept === 'function') { 11867 return dropAccept.call(receivingContext.calendarApi, el); 11868 } 11869 if (typeof dropAccept === 'string' && dropAccept) { 11870 return Boolean(elementMatches(el, dropAccept)); 11871 } 11872 return true; 11873 }; 11874 return ExternalElementDragging; 11875 }()); 11876 // Utils for computing event store from the DragMeta 11877 // ---------------------------------------------------------------------------------------------------- 11878 function computeEventForDateSpan(dateSpan, dragMeta, context) { 11879 var defProps = __assign({}, dragMeta.leftoverProps); 11880 for (var _i = 0, _a = context.pluginHooks.externalDefTransforms; _i < _a.length; _i++) { 11881 var transform = _a[_i]; 11882 __assign(defProps, transform(dateSpan, dragMeta)); 11883 } 11884 var _b = refineEventDef(defProps, context), refined = _b.refined, extra = _b.extra; 11885 var def = parseEventDef(refined, extra, dragMeta.sourceId, dateSpan.allDay, context.options.forceEventDuration || Boolean(dragMeta.duration), // hasEnd 11886 context); 11887 var start = dateSpan.range.start; 11888 // only rely on time info if drop zone is all-day, 11889 // otherwise, we already know the time 11890 if (dateSpan.allDay && dragMeta.startTime) { 11891 start = context.dateEnv.add(start, dragMeta.startTime); 11892 } 11893 var end = dragMeta.duration ? 11894 context.dateEnv.add(start, dragMeta.duration) : 11895 getDefaultEventEnd(dateSpan.allDay, start, context); 11896 var instance = createEventInstance(def.defId, { start: start, end: end }); 11897 return { def: def, instance: instance }; 11898 } 11899 // Utils for extracting data from element 11900 // ---------------------------------------------------------------------------------------------------- 11901 function getDragMetaFromEl(el) { 11902 var str = getEmbeddedElData(el, 'event'); 11903 var obj = str ? 11904 JSON.parse(str) : 11905 { create: false }; // if no embedded data, assume no event creation 11906 return parseDragMeta(obj); 11907 } 11908 config.dataAttrPrefix = ''; 11909 function getEmbeddedElData(el, name) { 11910 var prefix = config.dataAttrPrefix; 11911 var prefixedName = (prefix ? prefix + '-' : '') + name; 11912 return el.getAttribute('data-' + prefixedName) || ''; 11913 } 11914 11915 /* 11916 Makes an element (that is *external* to any calendar) draggable. 11917 Can pass in data that determines how an event will be created when dropped onto a calendar. 11918 Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system. 11919 */
11920 var ExternalDraggable = /** @class */ (function () { 11921 function ExternalDraggable(el, settings) { 11922 var _this = this; 11923 if (settings === void 0) { settings = {}; } 11924 this.handlePointerDown = function (ev) { 11925 var dragging = _this.dragging; 11926 var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay; 11927 dragging.minDistance = 11928 minDistance != null ? 11929 minDistance : 11930 (ev.isTouch ? 0 : BASE_OPTION_DEFAULTS.eventDragMinDistance); 11931 dragging.delay = 11932 ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv 11933 (longPressDelay != null ? longPressDelay : BASE_OPTION_DEFAULTS.longPressDelay) : 11934 0; 11935 }; 11936 this.handleDragStart = function (ev) { 11937 if (ev.isTouch && 11938 _this.dragging.delay && 11939 ev.subjectEl.classList.contains('fc-event')) { 11940 _this.dragging.mirror.getMirrorEl().classList.add('fc-event-selected'); 11941 } 11942 }; 11943 this.settings = settings; 11944 var dragging = this.dragging = new FeaturefulElementDragging(el); 11945 dragging.touchScrollAllowed = false; 11946 if (settings.itemSelector != null) { 11947 dragging.pointer.selector = settings.itemSelector; 11948 } 11949 if (settings.appendTo != null) { 11950 dragging.mirror.parentNode = settings.appendTo; // TODO: write tests 11951 } 11952 dragging.emitter.on('pointerdown', this.handlePointerDown); 11953 dragging.emitter.on('dragstart', this.handleDragStart); 11954 new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new 11955 } 11956 ExternalDraggable.prototype.destroy = function () { 11957 this.dragging.destroy(); 11958 }; 11959 return ExternalDraggable; 11960 }()); 11961 11962 /* 11963 Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements. 11964 The third-party system is responsible for drawing the visuals effects of the drag. 11965 This class simply monitors for pointer movements and fires events. 11966 It also has the ability to hide the moving element (the "mirror") during the drag. 11967 */ 11968 var InferredElementDragging = /** @class */ (function (_super) { 11969 __extends(InferredElementDragging, _super); 11970 function InferredElementDragging(containerEl) { 11971 var _this = _super.call(this, containerEl) || this; 11972 _this.shouldIgnoreMove = false; 11973 _this.mirrorSelector = ''; 11974 _this.currentMirrorEl = null; 11975 _this.handlePointerDown = function (ev) { 11976 _this.emitter.trigger('pointerdown', ev); 11977 if (!_this.shouldIgnoreMove) { 11978 // fire dragstart right away. does not support delay or min-distance 11979 _this.emitter.trigger('dragstart', ev); 11980 } 11981 }; 11982 _this.handlePointerMove = function (ev) { 11983 if (!_this.shouldIgnoreMove) { 11984 _this.emitter.trigger('dragmove', ev); 11985 } 11986 }; 11987 _this.handlePointerUp = function (ev) { 11988 _this.emitter.trigger('pointerup', ev); 11989 if (!_this.shouldIgnoreMove) { 11990 // fire dragend right away. does not support a revert animation 11991 _this.emitter.trigger('dragend', ev); 11992 } 11993 }; 11994 var pointer = _this.pointer = new PointerDragging(containerEl); 11995 pointer.emitter.on('pointerdown', _this.handlePointerDown); 11996 pointer.emitter.on('pointermove', _this.handlePointerMove); 11997 pointer.emitter.on('pointerup', _this.handlePointerUp); 11998 return _this; 11999 } 12000 InferredElementDragging.prototype.destroy = function () { 12001 this.pointer.destroy(); 12002 }; 12003 InferredElementDragging.prototype.setIgnoreMove = function (bool) { 12004 this.shouldIgnoreMove = bool; 12005 }; 12006 InferredElementDragging.prototype.setMirrorIsVisible = function (bool) { 12007 if (bool) { 12008 // restore a previously hidden element. 12009 // use the reference in case the selector class has already been removed. 12010 if (this.currentMirrorEl) { 12011 this.currentMirrorEl.style.visibility = ''; 12012 this.currentMirrorEl = null; 12013 } 12014 } 12015 else { 12016 var mirrorEl = this.mirrorSelector 12017 // TODO: somehow query FullCalendars WITHIN shadow-roots 12018 ? document.querySelector(this.mirrorSelector) 12019 : null; 12020 if (mirrorEl) { 12021 this.currentMirrorEl = mirrorEl; 12022 mirrorEl.style.visibility = 'hidden'; 12023 } 12024 } 12025 }; 12026 return InferredElementDragging; 12027 }(ElementDragging)); 12028 12029 /* 12030 Bridges third-party drag-n-drop systems with FullCalendar. 12031 Must be instantiated and destroyed by caller. 12032 */ 12033 var ThirdPartyDraggable = /** @class */ (function () { 12034 function ThirdPartyDraggable(containerOrSettings, settings) { 12035 var containerEl = document; 12036 if ( 12037 // wish we could just test instanceof EventTarget, but doesn't work in IE11 12038 containerOrSettings === document || 12039 containerOrSettings instanceof Element) { 12040 containerEl = containerOrSettings; 12041 settings = settings || {}; 12042 } 12043 else { 12044 settings = (containerOrSettings || {}); 12045 } 12046 var dragging = this.dragging = new InferredElementDragging(containerEl); 12047 if (typeof settings.itemSelector === 'string') { 12048 dragging.pointer.selector = settings.itemSelector; 12049 } 12050 else if (containerEl === document) { 12051 dragging.pointer.selector = '[data-event]'; 12052 } 12053 if (typeof settings.mirrorSelector === 'string') { 12054 dragging.mirrorSelector = settings.mirrorSelector; 12055 } 12056 new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new 12057 } 12058 ThirdPartyDraggable.prototype.destroy = function () { 12059 this.dragging.destroy(); 12060 }; 12061 return ThirdPartyDraggable; 12062 }()); 12063 12064 var interactionPlugin = createPlugin({ 12065 componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing], 12066 calendarInteractions: [UnselectAuto], 12067 elementDraggingImpl: FeaturefulElementDragging, 12068 optionRefiners: OPTION_REFINERS$3, 12069 listenerRefiners: LISTENER_REFINERS, 12070 });
12071 12072 /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells. 12073 ----------------------------------------------------------------------------------------------------------------------*/ 12074 // It is a manager for a Table subcomponent, which does most of the heavy lifting. 12075 // It is responsible for managing width/height. 12076 var TableView = /** @class */ (function (_super) { 12077 __extends(TableView, _super); 12078 function TableView() { 12079 var _this = _super !== null && _super.apply(this, arguments) || this; 12080 _this.headerElRef = createRef(); 12081 return _this; 12082 } 12083 TableView.prototype.renderSimpleLayout = function (headerRowContent, bodyContent) { 12084 var _a = this, props = _a.props, context = _a.context; 12085 var sections = []; 12086 var stickyHeaderDates = getStickyHeaderDates(context.options); 12087 if (headerRowContent) { 12088 sections.push({ 12089 type: 'header', 12090 key: 'header', 12091 isSticky: stickyHeaderDates, 12092 chunk: { 12093 elRef: this.headerElRef, 12094 tableClassName: 'fc-col-header', 12095 rowContent: headerRowContent, 12096 }, 12097 }); 12098 } 12099 sections.push({ 12100 type: 'body', 12101 key: 'body', 12102 liquid: true, 12103 chunk: { content: bodyContent }, 12104 }); 12105 return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygrid'].concat(classNames).join(' ') }, 12106 createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [] /* TODO: make optional? */, sections: sections }))); })); 12107 }; 12108 TableView.prototype.renderHScrollLayout = function (headerRowContent, bodyContent, colCnt, dayMinWidth) { 12109 var ScrollGrid = this.context.pluginHooks.scrollGridImpl; 12110 if (!ScrollGrid) { 12111 throw new Error('No ScrollGrid implementation'); 12112 } 12113 var _a = this, props = _a.props, context = _a.context; 12114 var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options); 12115 var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options); 12116 var sections = []; 12117 if (headerRowContent) { 12118 sections.push({ 12119 type: 'header', 12120 key: 'header', 12121 isSticky: stickyHeaderDates, 12122 chunks: [{ 12123 key: 'main', 12124 elRef: this.headerElRef, 12125 tableClassName: 'fc-col-header', 12126 rowContent: headerRowContent, 12127 }], 12128 }); 12129 } 12130 sections.push({ 12131 type: 'body', 12132 key: 'body', 12133 liquid: true, 12134 chunks: [{ 12135 key: 'main', 12136 content: bodyContent, 12137 }], 12138 }); 12139 if (stickyFooterScrollbar) { 12140 sections.push({ 12141 type: 'footer', 12142 key: 'footer', 12143 isSticky: true, 12144 chunks: [{ 12145 key: 'main', 12146 content: renderScrollShim, 12147 }], 12148 }); 12149 } 12150 return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygrid'].concat(classNames).join(' ') }, 12151 createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], sections: sections }))); })); 12152 }; 12153 return TableView; 12154 }(DateComponent)); 12155 12156 function splitSegsByRow(segs, rowCnt) { 12157 var byRow = []; 12158 for (var i = 0; i < rowCnt; i += 1) { 12159 byRow[i] = []; 12160 } 12161 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 12162 var seg = segs_1[_i]; 12163 byRow[seg.row].push(seg); 12164 } 12165 return byRow; 12166 } 12167 function splitSegsByFirstCol(segs, colCnt) { 12168 var byCol = []; 12169 for (var i = 0; i < colCnt; i += 1) { 12170 byCol[i] = []; 12171 } 12172 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 12173 var seg = segs_2[_i]; 12174 byCol[seg.firstCol].push(seg); 12175 } 12176 return byCol; 12177 } 12178 function splitInteractionByRow(ui, rowCnt) { 12179 var byRow = []; 12180 if (!ui) { 12181 for (var i = 0; i < rowCnt; i += 1) { 12182 byRow[i] = null; 12183 } 12184 } 12185 else { 12186 for (var i = 0; i < rowCnt; i += 1) { 12187 byRow[i] = { 12188 affectedInstances: ui.affectedInstances, 12189 isEvent: ui.isEvent, 12190 segs: [], 12191 }; 12192 } 12193 for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) { 12194 var seg = _a[_i]; 12195 byRow[seg.row].segs.push(seg); 12196 } 12197 } 12198 return byRow; 12199 } 12200 12201 var TableCellTop = /** @class */ (function (_super) { 12202 __extends(TableCellTop, _super); 12203 function TableCellTop() { 12204 return _super !== null && _super.apply(this, arguments) || this; 12205 } 12206 TableCellTop.prototype.render = function () { 12207 var props = this.props; 12208 var navLinkAttrs = buildNavLinkAttrs(this.context, props.date); 12209 return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraHookProps: props.extraHookProps, defaultContent: renderTopInner }, function (innerElRef, innerContent) { return ((innerContent || props.forceDayTop) && (createElement("div", { className: "fc-daygri
12209d-day-top", ref: innerElRef }, 12210 createElement("a", __assign({ id: props.dayNumberId, className: "fc-daygrid-day-number" }, navLinkAttrs), innerContent || createElement(Fragment, null, "\u00A0"))))); })); 12211 }; 12212 return TableCellTop; 12213 }(BaseComponent)); 12214 function renderTopInner(props) { 12215 return props.dayNumberText; 12216 } 12217 12218 var DEFAULT_TABLE_EVENT_TIME_FORMAT = createFormatter({ 12219 hour: 'numeric', 12220 minute: '2-digit', 12221 omitZeroMinute: true, 12222 meridiem: 'narrow', 12223 }); 12224 function hasListItemDisplay(seg) { 12225 var display = seg.eventRange.ui.display; 12226 return display === 'list-item' || (display === 'auto' && 12227 !seg.eventRange.def.allDay && 12228 seg.firstCol === seg.lastCol && // can't be multi-day 12229 seg.isStart && // " 12230 seg.isEnd // " 12231 ); 12232 } 12233 12234 var TableBlockEvent = /** @class */ (function (_super) { 12235 __extends(TableBlockEvent, _super); 12236 function TableBlockEvent() { 12237 return _super !== null && _super.apply(this, arguments) || this; 12238 } 12239 TableBlockEvent.prototype.render = function () { 12240 var props = this.props; 12241 return (createElement(StandardEvent, __assign({}
12241, props, { extraClassNames: ['fc-daygrid-event', 'fc-daygrid-block-event', 'fc-h-event'], defaultTimeFormat: DEFAULT_TABLE_EVENT_TIME_FORMAT, defaultDisplayEventEnd: props.defaultDisplayEventEnd, disableResizing: !props.seg.eventRange.def.allDay }))); 12242 }; 12243 return TableBlockEvent; 12244 }(BaseComponent)); 12245 12246 var TableListItemEvent = /** @class */ (function (_super) { 12247 __extends(TableListItemEvent, _super); 12248 function TableListItemEvent() { 12249 return _super !== null && _super.apply(this, arguments) || this; 12250 } 12251 TableListItemEvent.prototype.render = function () { 12252 var _a = this, props = _a.props, context = _a.context; 12253 var timeFormat = context.options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT; 12254 var timeText = buildSegTimeText(props.seg, timeFormat, context, true, props.defaultDisplayEventEnd); 12255 return (createElement(EventRoot, { seg: props.seg, timeText: timeText, defaultContent: renderInnerContent$2, isDragging: props.isDragging, isResizing: false, isDateSelecting: false, isSelected: props.isSelected, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent) { return ( // we don't use styles! 12256 createElement("a", __assign({ className: ['fc-daygrid-event', 'fc-daygri
12256d-dot-event'].concat(classNames).join(' '), ref: rootElRef }, getSegAnchorAttrs(props.seg, context)), innerContent)); })); 12257 }; 12258 return TableListItemEvent; 12259 }(BaseComponent)); 12260 function renderInnerContent$2(innerProps) { 12261 return (createElement(Fragment, null, 12262 createElement("div", { className: "fc-daygrid-event-dot", style: { borderColor: innerProps.borderColor || innerProps.backgroundColor } }), 12263 innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)), 12264 createElement("div", { className: "fc-event-title" }, innerProps.event.title || createElement(Fragment, null, "\u00A0")))); 12265 } 12266 12267 var TableCellMoreLink = /** @class */ (function (_super) { 12268 __extends(TableCellMoreLink, _super); 12269 function TableCellMoreLink() { 12270 var _this = _super !== null && _super.apply(this, arguments) || this; 12271 _this.compileSegs = memoize(compileSegs); 12272 return _this; 12273 } 12274 TableCellMoreLink.prototype.render = function () { 12275 var props = this.props; 12276 var _a = this.compileSegs(props.singlePlacements), allSegs = _a.allSegs, invisibleSegs = _a.invisibleSegs; 12277 return (createElement(MoreLinkRoot, { dateProfile: props.dateProfile, todayRange: props.todayRange, allDayDate: props.allDayDate, moreCnt: props.moreCnt, allSegs: allSegs, hiddenSegs: invisibleSegs, alignmentElRef: props.alignmentElRef, alignGridTop: props.alignGridTop, extraDateSpan: props.extraDateSpan, popoverContent: function () { 12278 var isForcedInvisible = (props.eventDrag ? props.eventDrag.affectedInstances : null) || 12279 (props.eventResize ? props.eventResize.affectedInstances : null) || 12280 {}; 12281 return (createElement(Fragment, null, allSegs.map(function (seg) { 12282 var instanceId = seg.eventRange.instance.instanceId; 12283 return (createElement("div", { className: "fc-daygrid-event-harness", key: instanceId, style: { 12284 visibility: isForcedInvisible[instanceId] ? 'hidden' : '', 12285 } }, hasListItemDisplay(seg) ? (createElement(TableListItemEvent, __assign({ seg: seg, isDragging: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, getSegMeta(seg, props.todayRange)))) : (createElement(TableBlockEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, getSegMeta(seg, props.todayRange)))))); 12286 }))); 12287 } }, function (rootElRef, classNames, innerElRef, innerContent, handleClick, title, isExpanded, popoverId) { return (createElement("a", __assign({ ref: rootElRef, className: ['fc-daygrid-more-link'].concat(classNames).join(' '), title: title, "aria-expanded": isExpanded, "aria-controls": popoverId }, createAriaClickAttrs(handleClick)), innerContent)); })); 12288 }; 12289 return TableCellMoreLink; 12290 }(BaseComponent)); 12291 function compileSegs(singlePlacements) { 12292 var allSegs = []; 12293 var invisibleSegs = []; 12294 for (var _i = 0, singlePlacements_1 = singlePlacements; _i < singlePlacements_1.length; _i++) { 12295 var placement = singlePlacements_1[_i]; 12296 allSegs.push(placement.seg); 12297 if (!placement.isVisible) { 12298 invisibleSegs.push(placement.seg); 12299 } 12300 } 12301 return { allSegs: allSegs, invisibleSegs: invisibleSegs }; 12302 } 12303 12304 var DEFAULT_WEEK_NUM_FORMAT$1 = createFormatter({ week: 'narrow' }); 12305 var TableCell = /** @class */ (function (_super) { 12306 __extends(TableCell, _super); 12307 function TableCell() { 12308 var _this = _super !== null && _super.apply(this, arguments) || this; 12309 _this.rootElRef = createRef(); 12310 _this.state = { 12311 dayNumberId: getUniqueDomId(), 12312 }; 12313 _this.handleRootEl = function (el) { 12314 setRef(_this.rootElRef, el); 12315 setRef(_this.props.elRef, el); 12316 }; 12317 return _this; 12318 } 12319 TableCell.prototype.render = function () {
12320 var _a = this, context = _a.context, props = _a.props, state = _a.state, rootElRef = _a.rootElRef; 12321 var date = props.date, dateProfile = props.dateProfile; 12322 var navLinkAttrs = buildNavLinkAttrs(context, date, 'week'); 12323 return (createElement(DayCellRoot, { date: date, dateProfile: dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraHookProps: props.extraHookProps, elRef: this.handleRootEl }, function (dayElRef, dayClassNames, rootDataAttrs, isDisabled) { return (createElement("td", __assign({ ref: dayElRef, role: "gridcell", className: ['fc-daygrid-day'].concat(dayClassNames, props.extraClassNames || []).join(' ') }, rootDataAttrs, props.extraDataAttrs, (props.showDayNumber ? { 'aria-labelledby': state.dayNumberId } : {})), 12324 createElement("div", { className: "fc-daygrid-day-frame fc-scrollgrid-sync-inner", ref: props.innerElRef /* different from hook system! RENAME */ }, 12325 props.showWeekNumber && (createElement(WeekNumberRoot, { date: date, defaultFormat: DEFAULT_WEEK_NUM_FORMAT$1 }, function (weekElRef, weekClassNames, innerElRef, innerContent) { return (createElement("a", __assign({ ref: weekElRef, className: ['fc-daygrid-week-number'].concat(weekClassNames).join(' ') }, navLinkAttrs), innerContent)); })), 12326 !isDisabled && (createElement(TableCellTop, { date: date, dateProfile: dateProfile, showDayNumber: props.showDayNumber, dayNumberId: state.dayNumberId, forceDayTop: props.forceDayTop, todayRange: props.todayRange, extraHookProps: props.extraHookProps })), 12327 createElement("div", { className: "fc-daygrid-day-events", ref: props.fgContentElRef }, 12328 props.fgContent, 12329 createElement("div", { className: "fc-daygrid-day-bottom", style: { marginTop: props.moreMarginTop } }, 12330 createElement(TableCellMoreLink, { allDayDate: date, singlePlacements: props.singlePlacements, moreCnt: props.moreCnt, alignmentElRef: rootElRef, alignGridTop: !props.showDayNumber, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange }))), 12331 createElement("div", { className: "fc-daygrid-day-bg" }, props.bgContent)))); })); 12332 }; 12333 return TableCell; 12334 }(DateComponent)); 12335 12336 function computeFgSegPlacement(segs, // assumed already sorted 12337 dayMaxEvents, dayMaxEventRows, strictOrder, eventInstanceHeights, maxContentHeight, cells) { 12338 var hierarchy = new DayGridSegHierarchy(); 12339 hierarchy.allowReslicing = true; 12340 hierarchy.strictOrder = strictOrder; 12341 if (dayMaxEvents === true || dayMaxEventRows === true) { 12342 hierarchy.maxCoord = maxContentHeight; 12343 hierarchy.hiddenConsumes = true; 12344 } 12345 else if (typeof dayMaxEvents === 'number') { 12346 hierarchy.maxStackCnt = dayMaxEvents; 12347 } 12348 else if (typeof dayMaxEventRows === 'number') { 12349 hierarchy.maxStackCnt = dayMaxEventRows; 12350 hierarchy.hiddenConsumes = true; 12351 } 12352 // create segInputs only for segs with known heights 12353 var segInputs = []; 12354 var unknownHeightSegs = []; 12355 for (var i = 0; i < segs.length; i += 1) { 12356 var seg = segs[i]; 12357 var instanceId = seg.eventRange.instance.instanceId; 12358 var eventHeight = eventInstanceHeights[instanceId]; 12359 if (eventHeight != null) { 12360 segInputs.push({ 12361 index: i, 12362 thickness: eventHeight, 12363 span: { 12364 start: seg.firstCol, 12365 end: seg.lastCol + 1, 12366 }, 12367 }); 12368 } 12369 else { 12370 unknownHeightSegs.push(seg); 12371 } 12372 } 12373 var hiddenEntries = hierarchy.addSegs(segInputs); 12374 var segRects = hierarchy.toRects(); 12375 var _a = placeRects(segRects, segs, cells), singleColPlacements = _a.singleColPlacements, multiColPlacements = _a.multiColPlacements, leftoverMargins = _a.leftoverMargins; 12376 var moreCnts = []; 12377 var moreMarginTops = []; 12378 // add segs with unknown heights 12379 for (var _i = 0, unknownHeightSegs_1 = unknownHeightSegs; _i < unknownHeightSegs_1.length; _i++) { 12380 var seg = unknownHeightSegs_1[_i]; 12381 multiColPlacements[seg.firstCol].push({ 12382 seg: seg, 12383 isVisible: false, 12384 isAbsolute: true, 12385 absoluteTop: 0, 12386 marginTop: 0, 12387 });
12388 for (var col = seg.firstCol; col <= seg.lastCol; col += 1) { 12389 singleColPlacements[col].push({ 12390 seg: resliceSeg(seg, col, col + 1, cells), 12391 isVisible: false, 12392 isAbsolute: false, 12393 absoluteTop: 0, 12394 marginTop: 0, 12395 }); 12396 } 12397 } 12398 // add the hidden entries 12399 for (var col = 0; col < cells.length; col += 1) { 12400 moreCnts.push(0); 12401 } 12402 for (var _b = 0, hiddenEntries_1 = hiddenEntries; _b < hiddenEntries_1.length; _b++) { 12403 var hiddenEntry = hiddenEntries_1[_b]; 12404 var seg = segs[hiddenEntry.index]; 12405 var hiddenSpan = hiddenEntry.span; 12406 multiColPlacements[hiddenSpan.start].push({ 12407 seg: resliceSeg(seg, hiddenSpan.start, hiddenSpan.end, cells), 12408 isVisible: false, 12409 isAbsolute: true, 12410 absoluteTop: 0, 12411 marginTop: 0, 12412 }); 12413 for (var col = hiddenSpan.start; col < hiddenSpan.end; col += 1) { 12414 moreCnts[col] += 1; 12415 singleColPlacements[col].push({ 12416 seg: resliceSeg(seg, col, col + 1, cells), 12417 isVisible: false, 12418 isAbsolute: false, 12419 absoluteTop: 0, 12420 marginTop: 0, 12421 }); 12422 } 12423 } 12424 // deal with leftover margins 12425 for (var col = 0; col < cells.length; col += 1) { 12426 moreMarginTops.push(leftoverMargins[col]); 12427 } 12428 return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, moreCnts: moreCnts, moreMarginTops: moreMarginTops }; 12429 } 12430 // rects ordered by top coord, then left 12431 function placeRects(allRects, segs, cells) { 12432 var rectsByEachCol = groupRectsByEachCol(allRects, cells.length); 12433 var singleColPlacements = []; 12434 var multiColPlacements = []; 12435 var leftoverMargins = []; 12436 for (var col = 0; col < cells.length; col += 1) { 12437 var rects = rectsByEachCol[col]; 12438 // compute all static segs in singlePlacements 12439 var singlePlacements = []; 12440 var currentHeight = 0; 12441 var currentMarginTop = 0; 12442 for (var _i = 0, rects_1 = rects; _i < rects_1.length; _i++) { 12443 var rect = rects_1[_i]; 12444 var seg = segs[rect.index]; 12445 singlePlacements.push({ 12446 seg: resliceSeg(seg, col, col + 1, cells), 12447 isVisible: true, 12448 isAbsolute: false, 12449 absoluteTop: rect.levelCoord, 12450 marginTop: rect.levelCoord - currentHeight, 12451 }); 12452 currentHeight = rect.levelCoord + rect.thickness; 12453 } 12454 // compute mixed static/absolute segs in multiPlacements 12455 var multiPlacements = []; 12456 currentHeight = 0; 12457 currentMarginTop = 0; 12458 for (var _a = 0, rects_2 = rects; _a < rects_2.length; _a++) { 12459 var rect = rects_2[_a]; 12460 var seg = segs[rect.index]; 12461 var isAbsolute = rect.span.end - rect.span.start > 1; // multi-column? 12462 var isFirstCol = rect.span.start === col; 12463 currentMarginTop += rect.levelCoord - currentHeight; // amount of space since bottom of previous seg 12464 currentHeight = rect.levelCoord + rect.thickness; // height will now be bottom of current seg 12465 if (isAbsolute) { 12466 currentMarginTop += rect.thickness; 12467 if (isFirstCol) { 12468 multiPlacements.push({ 12469 seg: resliceSeg(seg, rect.span.start, rect.span.end, cells), 12470 isVisible: true, 12471 isAbsolute: true, 12472 absoluteTop: rect.levelCoord, 12473 marginTop: 0, 12474 }); 12475 } 12476 } 12477 else if (isFirstCol) { 12478 multiPlacements.push({ 12479 seg: resliceSeg(seg, rect.span.start, rect.span.end, cells), 12480 isVisible: true, 12481 isAbsolute: false, 12482 absoluteTop: rect.levelCoord, 12483 marginTop: currentMarginTop, // claim the margin 12484 }); 12485 currentMarginTop = 0; 12486 } 12487 } 12488 singleColPlacements.push(singlePlacements); 12489 multiColPlacements.push(multiPlacements); 12490 leftoverMargins.push(currentMarginTop); 12491 } 12492 return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, leftoverMargins: leftoverMargins }; 12493 } 12494 function groupRectsByEachCol(rects, colCnt) { 12495 var rectsByEachCol = []; 12496 for (var col = 0; col < colCnt; col += 1) { 12497 rectsByEachCol.push([]); 12498 } 12499 for (var _i = 0, rects_3 = rects; _i < rects_3.length; _i++) { 12500 var rect = rects_3[_i]; 12501 for (var col = rect.span.start; col < rect.span.end; col += 1) { 12502 rectsByEachCol[col].push(rect); 12503 } 12504 } 12505 return rectsByEachCol; 12506 } 12507 function resliceSeg(seg, spanStart, spanEnd, cells) { 12508 if (seg.firstCol === spanStart && seg.lastCol === spanEnd - 1) { 12509 return seg; 12510 } 12511 var eventRange = seg.eventRange; 12512 var origRange = eventRange.range; 12513 var slicedRange = intersectRanges(origRange, { 12514 start: cells[spanStart].date, 12515 end: addDays(cells[spanEnd - 1].date, 1), 12516 }); 12517 return __assign(__assign({}, seg), { firstCol: spanStart, lastCol: spanEnd - 1, eventRange: { 12518 def: eventRange.def, 12519 ui: __assign(__assign({}, eventRange.ui), { durationEditable: false }), 12520 instance: eventRange.instance, 12521 range: slicedRange, 12522 }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() }); 12523 } 12524 var DayGridSegHierarchy = /** @class */ (function (_super) { 12525 __extends(DayGridSegHierarchy, _super); 12526 function DayGridSegHierarchy() { 12527 var _this = _super !== null && _super.apply(this, arguments) || this; 12528 // config 12529 _this.hiddenConsumes = false; 12530 // allows us to keep hidden entries in the hierarchy so they take up space 12531 _this.forceHidden = {}; 12532 return _this; 12533 } 12534 DayGridSegHierarchy.prototype.addSegs = function (segInputs) { 12535 var _this = this; 12536 var hiddenSegs = _super.prototype.addSegs.call(this, segInputs); 12537 var entriesByLevel = this.entriesByLevel; 12538 var excludeHidden = function (entry) { return !_this.forceHidden[buildEntryKey(entry)]; }; 12539 // remove the forced-hidden segs 12540 for (var level = 0; level < entriesByLevel.length; level += 1) {
12541 entriesByLevel[level] = entriesByLevel[level].filter(excludeHidden); 12542 } 12543 return hiddenSegs; 12544 }; 12545 DayGridSegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) { 12546 var _a = this, entriesByLevel = _a.entriesByLevel, forceHidden = _a.forceHidden; 12547 var touchingEntry = insertion.touchingEntry, touchingLevel = insertion.touchingLevel, touchingLateral = insertion.touchingLateral; 12548 if (this.hiddenConsumes && touchingEntry) { 12549 var touchingEntryId = buildEntryKey(touchingEntry); 12550 // if not already hidden 12551 if (!forceHidden[touchingEntryId]) { 12552 if (this.allowReslicing) { 12553 var placeholderEntry = __assign(__assign({}, touchingEntry), { span: intersectSpans(touchingEntry.span, entry.span) }); 12554 var placeholderEntryId = buildEntryKey(placeholderEntry); 12555 forceHidden[placeholderEntryId] = true; 12556 entriesByLevel[touchingLevel][touchingLateral] = placeholderEntry; // replace touchingEntry with our placeholder 12557 this.splitEntry(touchingEntry, entry, hiddenEntries); // split up the touchingEntry, reinsert it 12558 } 12559 else { 12560 forceHidden[touchingEntryId] = true; 12561 hiddenEntries.push(touchingEntry); 12562 } 12563 } 12564 } 12565 return _super.prototype.handleInvalidInsertion.call(this, insertion, entry, hiddenEntries); 12566 }; 12567 return DayGridSegHierarchy; 12568 }(SegHierarchy)); 12569 12570 var TableRow = /** @class */ (function (_super) { 12571 __extends(TableRow, _super); 12572 function TableRow() { 12573 var _this = _super !== null && _super.apply(this, arguments) || this; 12574 _this.cellElRefs = new RefMap(); // the <td> 12575 _this.frameElRefs = new RefMap(); // the fc-daygrid-day-frame 12576 _this.fgElRefs = new RefMap(); // the fc-daygrid-day-events 12577 _this.segHarnessRefs = new RefMap(); // indexed by "instanceId:firstCol" 12578 _this.rootElRef = createRef(); 12579 _this.state = { 12580 framePositions: null, 12581 maxContentHeight: null, 12582 eventInstanceHeights: {}, 12583 }; 12584 return _this; 12585 } 12586 TableRow.prototype.render = function () { 12587 var _this = this; 12588 var _a = this, props = _a.props, state = _a.state, context = _a.context; 12589 var options = context.options; 12590 var colCnt = props.cells.length; 12591 var businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt); 12592 var bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt); 12593 var highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt); 12594 var mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt); 12595 var _b = computeFgSegPlacement(sortEventSegs(props.fgEventSegs, options.eventOrder), props.dayMaxEvents, props.dayMaxEventRows, options.eventOrderStrict, state.eventInstanceHeights, state.maxContentHeight, props.cells), singleColPlacements = _b.singleColPlacements, multiColPlacements = _b.multiColPlacements, moreCnts = _b.moreCnts, moreMarginTops = _b.moreMarginTops; 12596 var isForcedInvisible = // TODO: messy way to compute this 12597 (props.eventDrag && props.eventDrag.affectedInstances) || 12598 (props.eventResize && props.eventResize.affectedInstances) || 12599 {}; 12600 return (createElement("tr", { ref: this.rootElRef, role: "row" }, 12601 props.renderIntro && props.renderIntro(), 12602 props.cells.map(function (cell, col) { 12603 var normalFgNodes = _this.renderFgSegs(col, props.forPrint ? singleColPlacements[col] : multiColPlacements[col], props.todayRange, isForcedInvisible); 12604 var mirrorFgNodes = _this.renderFgSegs(col, buildMirrorPlacements(mirrorSegsByCol[col], multiColPlacements), props.todayRange, {}, Boolean(props.eventDrag), Boolean(props.eventResize), false); 12605 return (createElement(TableCell, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), innerElRef: _this.frameElRefs.createRef(cell.key) /* FF <td> problem, but okay to use for left/right. TODO: rename prop */, dateProfile: props.dateProfile, date: cell.date, showDayNumber: props.showDayNumbers, showWeekNumber: props.showWeekNumbers && col === 0, forceDayTop: props.showWeekNumbers /* even displaying weeknum for row, not necessarily day */, todayRange: props.todayRange, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, moreCnt: moreCnts[col], moreMarginTop: moreMarginTops[col], singlePlacements: singleColPlacements[col], fgContentElRef: _this.fgElRefs.createRef(cell.key), fgContent: ( // Fragment scopes the keys 12606 createElement(Fragment, null, 12607 createElement(Fragment, null, normalFgNodes), 12608 createElement(Fragment, null, mirrorFgNodes))), bgContent: ( // Fragment scopes the keys 12609 createElement(Fragment, null, 12610 _this.renderFillSegs(highlightSegsByCol[col], 'highlight'), 12611 _this.renderFillSegs(businessHoursByCol[col], 'non-business'), 12612 _this.renderFillSegs(bgEventSegsByCol[col], 'bg-event'))) })); 12613 }))); 12614 }; 12615 TableRow.prototype.componentDidMount = function () { 12616 this.updateSizing(true); 12617 }; 12618 TableRow.prototype.componentDidUpdate = function (prevProps, prevState) { 12619 var currentProps = this.props; 12620 this.updateSizing(!isPropsEqual(prevProps, currentProps)); 12621 }; 12622 TableRow.prototype.getHighlightSegs = function () { 12623 var props = this.props; 12624 if (props.eventDrag && props.eventDrag.segs.length) { // messy check 12625 return props.eventDrag.segs; 12626 } 12627 if (props.eventResize && props.eventResize.segs.length) { // messy check 12628 return props.eventResize.segs; 12629 } 12630 return props.dateSelectionSegs; 12631 }; 12632 TableRow.prototype.getMirrorSegs = function () { 12633 var props = this.props; 12634 if (props.eventResize && props.eventResize.segs.length) { // messy check 12635 return props.eventResize.segs; 12636 } 12637 return []; 12638 }; 12639 TableRow.prototype.renderFgSegs = function (col, segPlacements, todayRange, isForcedInvisible, isDragging, isResizing, isDateSelecting) { 12640 var context = this.context; 12641 var eventSelection = this.props.eventSelection; 12642 var framePositions = this.state.framePositions; 12643 var defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1 12644 var isMirror = isDragging || isResizing || isDateSelecting; 12645 var nodes = []; 12646 if (framePositions) { 12647 for (var _i = 0, segPlacements_1 = segPlacements; _i < segPlacements_1.length; _i++) { 12648 var placement = segPlacements_1[_i]; 12649 var seg = placement.seg; 12650 var instanceId = seg.eventRange.instance.instanceId; 12651 var key = instanceId + ':' + col; 12652 var isVisible = placement.isVisible && !isForcedInvisible[instanceId];
12653 var isAbsolute = placement.isAbsolute; 12654 var left = ''; 12655 var right = ''; 12656 if (isAbsolute) { 12657 if (context.isRtl) { 12658 right = 0; 12659 left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol]; 12660 } 12661 else { 12662 left = 0; 12663 right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol]; 12664 } 12665 } 12666 /* 12667 known bug: events that are force to be list-item but span multiple days still take up space in later columns 12668 todo: in print view, for multi-day events, don't display title within non-start/end segs 12669 */ 12670 nodes.push(createElement("div", { className: 'fc-daygrid-event-harness' + (isAbsolute ? ' fc-daygrid-event-harness-abs' : ''), key: key, ref: isMirror ? null : this.segHarnessRefs.createRef(key), style: { 12671 visibility: isVisible ? '' : 'hidden', 12672 marginTop: isAbsolute ? '' : placement.marginTop, 12673 top: isAbsolute ? placement.absoluteTop : '', 12674 left: left, 12675 right: right, 12676 } }, hasListItemDisplay(seg) ? (createElement(TableListItemEvent, __assign({ seg: seg, isDragging: isDragging, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange)))) : (createElement(TableBlockEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange)))))); 12677 } 12678 } 12679 return nodes; 12680 }; 12681 TableRow.prototype.renderFillSegs = function (segs, fillType) { 12682 var isRtl = this.context.isRtl; 12683 var todayRange = this.props.todayRange; 12684 var framePositions = this.state.framePositions; 12685 var nodes = []; 12686 if (framePositions) { 12687 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 12688 var seg = segs_1[_i]; 12689 var leftRightCss = isRtl ? { 12690 right: 0, 12691 left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol], 12692 } : { 12693 left: 0, 12694 right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol], 12695 }; 12696 nodes.push(createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-daygrid-bg-harness", style: leftRightCss }, fillType === 'bg-event' ? 12697 createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, todayRange))) : 12698 renderFill(fillType))); 12699 } 12700 } 12701 return createElement.apply(void 0, __spreadArray([Fragment, {}], nodes)); 12702 }; 12703 TableRow.prototype.updateSizing = function (isExternalSizingChange) { 12704 var _a = this, props = _a.props, frameElRefs = _a.frameElRefs; 12705 if (!props.forPrint && 12706 props.clientWidth !== null // positioning ready? 12707 ) { 12708 if (isExternalSizingChange) { 12709 var frameEls = props.cells.map(function (cell) { return frameElRefs.currentMap[cell.key]; }); 12710 if (frameEls.length) { 12711 var originEl = this.rootElRef.current; 12712 this.setState({ 12713 framePositions: new PositionCache(originEl, frameEls, true, // isHorizontal 12714 false), 12715 }); 12716 } 12717 } 12718 var oldInstanceHeights = this.state.eventInstanceHeights; 12719 var newInstanceHeights = this.queryEventInstanceHeights();
12720 var limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true; 12721 this.setState({ 12722 // HACK to prevent oscillations of events being shown/hidden from max-event-rows 12723 // Essentially, once you compute an element's height, never null-out. 12724 // TODO: always display all events, as visibility:hidden? 12725 eventInstanceHeights: __assign(__assign({}, oldInstanceHeights), newInstanceHeights), 12726 maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null, 12727 }); 12728 } 12729 }; 12730 TableRow.prototype.queryEventInstanceHeights = function () { 12731 var segElMap = this.segHarnessRefs.currentMap; 12732 var eventInstanceHeights = {}; 12733 // get the max height amongst instance segs 12734 for (var key in segElMap) { 12735 var height = Math.round(segElMap[key].getBoundingClientRect().height); 12736 var instanceId = key.split(':')[0]; // deconstruct how renderFgSegs makes the key 12737 eventInstanceHeights[instanceId] = Math.max(eventInstanceHeights[instanceId] || 0, height); 12738 } 12739 return eventInstanceHeights; 12740 }; 12741 TableRow.prototype.computeMaxContentHeight = function () { 12742 var firstKey = this.props.cells[0].key; 12743 var cellEl = this.cellElRefs.currentMap[firstKey]; 12744 var fcContainerEl = this.fgElRefs.currentMap[firstKey]; 12745 return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top; 12746 }; 12747 TableRow.prototype.getCellEls = function () { 12748 var elMap = this.cellElRefs.currentMap; 12749 return this.props.cells.map(function (cell) { return elMap[cell.key]; }); 12750 }; 12751 return TableRow; 12752 }(DateComponent)); 12753 TableRow.addStateEquality({ 12754 eventInstanceHeights: isPropsEqual, 12755 }); 12756 function buildMirrorPlacements(mirrorSegs, colPlacements) { 12757 if (!mirrorSegs.length) { 12758 return []; 12759 } 12760 var topsByInstanceId = buildAbsoluteTopHash(colPlacements); // TODO: cache this at first render? 12761 return mirrorSegs.map(function (seg) { return ({ 12762 seg: seg, 12763 isVisible: true, 12764 isAbsolute: true, 12765 absoluteTop: topsByInstanceId[seg.eventRange.instance.instanceId], 12766 marginTop: 0, 12767 }); }); 12768 } 12769 function buildAbsoluteTopHash(colPlacements) { 12770 var topsByInstanceId = {}; 12771 for (var _i = 0, colPlacements_1 = colPlacements; _i < colPlacements_1.length; _i++) { 12772 var placements = colPlacements_1[_i]; 12773 for (var _a = 0, placements_1 = placements; _a < placements_1.length; _a++) { 12774 var placement = placements_1[_a]; 12775 topsByInstanceId[placement.seg.eventRange.instance.instanceId] = placement.absoluteTop; 12776 } 12777 } 12778 return topsByInstanceId; 12779 } 12780 12781 var Table = /** @class */ (function (_super) { 12782 __extends(Table, _super); 12783 function Table() { 12784 var _this = _super !== null && _super.apply(this, arguments) || this; 12785 _this.splitBusinessHourSegs = memoize(splitSegsByRow); 12786 _this.splitBgEventSegs = memoize(splitSegsByRow); 12787 _this.splitFgEventSegs = memoize(splitSegsByRow); 12788 _this.splitDateSelectionSegs = memoize(splitSegsByRow); 12789 _this.splitEventDrag = memoize(splitInteractionByRow); 12790 _this.splitEventResize = memoize(splitInteractionByRow); 12791 _this.rowRefs = new RefMap(); 12792 _this.handleRootEl = function (rootEl) { 12793 _this.rootEl = rootEl; 12794 if (rootEl) { 12795 _this.context.registerInteractiveComponent(_this, { 12796 el: rootEl, 12797 isHitComboAllowed: _this.props.isHitComboAllowed, 12798 }); 12799 } 12800 else { 12801 _this.context.unregisterInteractiveComponent(_this); 12802 } 12803 }; 12804 return _this; 12805 } 12806 Table.prototype.render = function () { 12807 var _this = this; 12808 var props = this.props; 12809 var dateProfile = props.dateProfile, dayMaxEventRows = props.dayMaxEventRows, dayMaxEvents = props.dayMaxEvents, expandRows = props.expandRows; 12810 var rowCnt = props.cells.length; 12811 var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt); 12812 var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt); 12813 var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt); 12814 var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt); 12815 var eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt); 12816 var eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt); 12817 var limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true; 12818 // if rows can't expand to fill fixed height, can't do balanced-height event limit 12819 // TODO: best place to normalize these options? 12820 if (limitViaBalanced && !expandRows) { 12821 limitViaBalanced = false; 12822 dayMaxEventRows = null; 12823 dayMaxEvents = null; 12824 } 12825 var classNames = [
12826 'fc-daygrid-body', 12827 limitViaBalanced ? 'fc-daygrid-body-balanced' : 'fc-daygrid-body-unbalanced', 12828 expandRows ? '' : 'fc-daygrid-body-natural', // will height of one row depend on the others? 12829 ]; 12830 return (createElement("div", { className: classNames.join(' '), ref: this.handleRootEl, style: { 12831 // these props are important to give this wrapper correct dimensions for interactions 12832 // TODO: if we set it here, can we avoid giving to inner tables? 12833 width: props.clientWidth, 12834 minWidth: props.tableMinWidth, 12835 } }, 12836 createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement(Fragment, null, 12837 createElement("table", { role: "presentation", className: "fc-scrollgrid-sync-table", style: { 12838 width: props.clientWidth, 12839 minWidth: props.tableMinWidth, 12840 height: expandRows ? props.clientHeight : '', 12841 } }, 12842 props.colGroupNode, 12843 createElement("tbody", { role: "presentation" }, props.cells.map(function (cells, row) { return (createElement(TableRow, { ref: _this.rowRefs.createRef(row), key: cells.length 12844 ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */ 12845 : row // in case there are no cells (like when resource view is loading) 12846 , showDayNumbers: rowCnt > 1, showWeekNumbers: props.showWeekNumbers, todayRange: todayRange, dateProfile: dateProfile, cells: cells, renderIntro: props.renderRowIntro, businessHourSegs: businessHourSegsByRow[row], eventSelection: props.eventSelection, bgEventSegs: bgEventSegsByRow[row].filter(isSegAllDay) /* hack */, fgEventSegs: fgEventSegsByRow[row], dateSelectionSegs: dateSelectionSegsByRow[row], eventDrag: eventDragByRow[row], eventResize: eventResizeByRow[row], dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint })); }))))); }))); 12847 }; 12848 // Hit System 12849 // ---------------------------------------------------------------------------------------------------- 12850 Table.prototype.prepareHits = function () { 12851 this.rowPositions = new PositionCache(this.rootEl, this.rowRefs.collect().map(function (rowObj) { return rowObj.getCellEls()[0]; }), // first cell el in each row. TODO: not optimal 12852 false, true); 12853 this.colPositions = new PositionCache(this.rootEl, this.rowRefs.currentMap[0].getCellEls(), // cell els in first row 12854 true, // horizontal 12855 false); 12856 }; 12857 Table.prototype.queryHit = function (positionLeft, positionTop) { 12858 var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions; 12859 var col = colPositions.leftToIndex(positionLeft); 12860 var row = rowPositions.topToIndex(positionTop); 12861 if (row != null && col != null) { 12862 var cell = this.props.cells[row][col]; 12863 return { 12864 dateProfile: this.props.dateProfile, 12865 dateSpan: __assign({ range: this.getCellRange(row, col), allDay: true }, cell.extraDateSpan), 12866 dayEl: this.getCellEl(row, col), 12867 rect: { 12868 left: colPositions.lefts[col], 12869 right: colPositions.rights[col], 12870 top: rowPositions.tops[row], 12871 bottom: rowPositions.bottoms[row], 12872 }, 12873 layer: 0, 12874 }; 12875 } 12876 return null; 12877 }; 12878 Table.prototype.getCellEl = function (row, col) { 12879 return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal 12880 }; 12881 Table.prototype.getCellRange = function (row, col) { 12882 var start = this.props.cells[row][col].date; 12883 var end = addDays(start, 1); 12884 return { start: start, end: end }; 12885 }; 12886 return Table; 12887 }(DateComponent)); 12888 function isSegAllDay(seg) { 12889 return seg.eventRange.def.allDay; 12890 } 12891 12892 var DayTableSlicer = /** @class */ (function (_super) { 12893 __extends(DayTableSlicer, _super); 12894 function DayTableSlicer() { 12895 var _this = _super !== null && _super.apply(this, arguments) || this; 12896 _this.forceDayIfListItem = true; 12897 return _this; 12898 } 12899 DayTableSlicer.prototype.sliceRange = function (dateRange, dayTableModel) { 12900 return dayTableModel.sliceRange(dateRange); 12901 }; 12902 return DayTableSlicer; 12903 }(Slicer));
12904 12905 var DayTable = /** @class */ (function (_super) { 12906 __extends(DayTable, _super); 12907 function DayTable() { 12908 var _this = _super !== null && _super.apply(this, arguments) || this; 12909 _this.slicer = new DayTableSlicer(); 12910 _this.tableRef = createRef(); 12911 return _this; 12912 } 12913 DayTable.prototype.render = function () { 12914 var _a = this, props = _a.props, context = _a.context; 12915 return (createElement(Table, __assign({ ref: this.tableRef }, this.slicer.sliceProps(props, props.dateProfile, props.nextDayThreshold, context, props.dayTableModel), { dateProfile: props.dateProfile, cells: props.dayTableModel.cells, colGroupNode: props.colGroupNode, tableMinWidth: props.tableMinWidth, renderRowIntro: props.renderRowIntro, dayMaxEvents: props.dayMaxEvents, dayMaxEventRows: props.dayMaxEventRows, showWeekNumbers: props.showWeekNumbers, expandRows: props.expandRows, headerAlignElRef: props.headerAlignElRef, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint }))); 12916 }; 12917 return DayTable; 12918 }(DateComponent)); 12919 12920 var DayTableView = /** @class */ (function (_super) { 12921 __extends(DayTableView, _super); 12922 function DayTableView() { 12923 var _this = _super !== null && _super.apply(this, arguments) || this; 12924 _this.buildDayTableModel = memoize(buildDayTableModel); 12925 _this.headerRef = createRef(); 12926 _this.tableRef = createRef(); 12927 return _this; 12928 } 12929 DayTableView.prototype.render = function () { 12930 var _this = this; 12931 var _a = this.context, options = _a.options, dateProfileGenerator = _a.dateProfileGenerator; 12932 var props = this.props; 12933 var dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator); 12934 var headerContent = options.dayHeaders && (createElement(DayHeader, { ref: this.headerRef, dateProfile: props.dateProfile, dates: dayTableModel.headerDates, datesRepDistinctDays: dayTableModel.rowCnt === 1 })); 12935 var bodyContent = function (contentArg) { return (createElement(DayTable, { ref: _this.tableRef, dateProfile: props.dateProfile, dayTableModel: dayTableModel, businessHours: props.businessHours, dateSelection: props.dateSelection, eventStore: props.eventStore, eventUiBases: props.eventUiBases, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, nextDayThreshold: options.nextDayThreshold, colGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, dayMaxEvents: options.dayMaxEvents, dayMaxEventRows: options.dayMaxEventRows, showWeekNumbers: options.weekNumbers, expandRows: !props.isHeightAuto, headerAlignElRef: _this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint })); }; 12936 return options.dayMinWidth 12937 ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth) 12938 : this.renderSimpleLayout(headerContent, bodyContent); 12939 }; 12940 return DayTableView; 12941 }(TableView)); 12942 function buildDayTableModel(dateProfile, dateProfileGenerator) {
12943 var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator); 12944 return new DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit)); 12945 } 12946 12947 var TableDateProfileGenerator = /** @class */ (function (_super) { 12948 __extends(TableDateProfileGenerator, _super); 12949 function TableDateProfileGenerator() { 12950 return _super !== null && _super.apply(this, arguments) || this; 12951 } 12952 // Computes the date range that will be rendered. 12953 TableDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) { 12954 var dateEnv = this.props.dateEnv; 12955 var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay); 12956 var start = renderRange.start; 12957 var end = renderRange.end; 12958 var endOfWeek; 12959 // year and month views should be aligned with weeks. this is already done for week 12960 if (/^(year|month)$/.test(currentRangeUnit)) { 12961 start = dateEnv.startOfWeek(start); 12962 // make end-of-week if not already 12963 endOfWeek = dateEnv.startOfWeek(end); 12964 if (endOfWeek.valueOf() !== end.valueOf()) { 12965 end = addWeeks(endOfWeek, 1); 12966 } 12967 } 12968 // ensure 6 weeks 12969 if (this.props.monthMode && 12970 this.props.fixedWeekCount) { 12971 var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays 12972 diffWeeks(start, end)); 12973 end = addWeeks(end, 6 - rowCnt); 12974 } 12975 return { start: start, end: end }; 12976 }; 12977 return TableDateProfileGenerator; 12978 }(DateProfileGenerator)); 12979 12980 var dayGridPlugin = createPlugin({ 12981 initialView: 'dayGridMonth', 12982 views: { 12983 dayGrid: { 12984 component: DayTableView, 12985 dateProfileGeneratorClass: TableDateProfileGenerator, 12986 }, 12987 dayGridDay: { 12988 type: 'dayGrid', 12989 duration: { days: 1 }, 12990 }, 12991 dayGridWeek: { 12992 type: 'dayGrid', 12993 duration: { weeks: 1 }, 12994 }, 12995 dayGridMonth: { 12996 type: 'dayGrid', 12997 duration: { months: 1 }, 12998 monthMode: true, 12999 fixedWeekCount: true, 13000 }, 13001 }, 13002 }); 13003 13004 var AllDaySplitter = /** @class */ (function (_super) { 13005 __extends(AllDaySplitter, _super); 13006 function AllDaySplitter() { 13007 return _super !== null && _super.apply(this, arguments) || this; 13008 } 13009 AllDaySplitter.prototype.getKeyInfo = function () { 13010 return { 13011 allDay: {}, 13012 timed: {}, 13013 }; 13014 }; 13015 AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) { 13016 if (dateSpan.allDay) { 13017 return ['allDay']; 13018 } 13019 return ['timed']; 13020 }; 13021 AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) { 13022 if (!eventDef.allDay) { 13023 return ['timed']; 13024 } 13025 if (hasBgRendering(eventDef)) { 13026 return ['timed', 'allDay']; 13027 } 13028 return ['allDay']; 13029 }; 13030 return AllDaySplitter; 13031 }(Splitter)); 13032 13033 var DEFAULT_SLAT_LABEL_FORMAT = createFormatter({ 13034 hour: 'numeric', 13035 minute: '2-digit', 13036 omitZeroMinute: true, 13037 meridiem: 'short', 13038 }); 13039 function TimeColsAxisCell(props) { 13040 var classNames = [ 13041 'fc-timegrid-slot', 13042 'fc-timegrid-slot-label', 13043 props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor', 13044 ]; 13045 return (createElement(ViewContextType.Consumer, null, function (context) { 13046 if (!props.isLabeled) { 13047 return (createElement("td", { className: classNames.join(' '), "data-time": props.isoTimeStr })); 13048 } 13049 var dateEnv = context.dateEnv, options = context.options, viewApi = context.viewApi; 13050 var labelFormat = // TODO: fully pre-parse 13051 options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT : 13052 Array.isArray(options.slotLabelFormat) ? createFormatter(options.slotLabelFormat[0]) : 13053 createFormatter(options.slotLabelFormat); 13054 var hookProps = { 13055 level: 0, 13056 time: props.time, 13057 date: dateEnv.toDate(props.date), 13058 view: viewApi, 13059 text: dateEnv.format(props.date, labelFormat), 13060 }; 13061 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.slotLabelClassNames, content: options.slotLabelContent, defaultContent: renderInnerContent$1, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: classNames.c
13061oncat(customClassNames).join(' '), "data-time": props.isoTimeStr }, 13062 createElement("div", { className: "fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame" }, 13063 createElement("div", { className: "fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion", ref: innerElRef }, innerContent)))); })); 13064 })); 13065 } 13066 function renderInnerContent$1(props) { 13067 return props.text; 13068 } 13069 13070 var TimeBodyAxis = /** @class */ (function (_super) { 13071 __extends(TimeBodyAxis, _super); 13072 function TimeBodyAxis() { 13073 return _super !== null && _super.apply(this, arguments) || this; 13074 } 13075 TimeBodyAxis.prototype.render = function () { 13076 return this.props.slatMetas.map(function (slatMeta) { return (createElement("tr", { key: slatMeta.key }, 13077 createElement(TimeColsAxisCell, __assign({}, slatMeta)))); }); 13078 }; 13079 return TimeBodyAxis; 13080 }(BaseComponent)); 13081 13082 var DEFAULT_WEEK_NUM_FORMAT = createFormatter({ week: 'short' }); 13083 var AUTO_ALL_DAY_MAX_EVENT_ROWS = 5; 13084 var TimeColsView = /** @class */ (function (_super) { 13085 __extends(TimeColsView, _super); 13086 function TimeColsView() { 13087 var _this = _super !== null && _super.apply(this, arguments) || this; 13088 _this.allDaySplitter = new AllDaySplitter(); // for use by subclasses 13089 _this.headerElRef = createRef(); 13090 _this.rootElRef = createRef(); 13091 _this.scrollerElRef = createRef(); 13092 _this.state = { 13093 slatCoords: null, 13094 }; 13095 _this.handleScrollTopRequest = function (scrollTop) { 13096 var scrollerEl = _this.scrollerElRef.current; 13097 if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer 13098 scrollerEl.scrollTop = scrollTop; 13099 } 13100 }; 13101 /* Header Render Methods 13102 ------------------------------------------------------------------------------------------------------------------*/ 13103 _this.renderHeadAxis = function (rowKey, frameHeight) { 13104 if (frameHeight === void 0) { frameHeight = ''; } 13105 var options = _this.context.options; 13106 var dateProfile = _this.props.dateProfile; 13107 var range = dateProfile.renderRange; 13108 var dayCnt = diffDays(range.start, range.end); 13109 var navLinkAttrs = (dayCnt === 1) // only do in day views (to avoid doing in week views that dont need it) 13110 ? buildNavLinkAttrs(_this.context, range.start, 'week') 13111 : {}; 13112 if (options.weekNumbers && rowKey === 'day') { 13113 return (createElement(WeekNumberRoot, { date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("th", { ref: rootElRef, "aria-hidden": true, className: [ 13114 'fc-timegrid-axis', 13115 'fc-scrollgrid-shrink', 13116 ].concat(classNames).join(' ') }, 13117 createElement("div", { className: "fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid", style: { height: frameHeight } }, 13118 createElement("a", __assign({ ref: innerElRef, className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner" }, navLinkAttrs), innerContent)))); })); 13119 } 13120 return (createElement("th", { "aria-hidden": true, className: "fc-timegrid-axis" }, 13121 createElement("div", { className: "fc-timegrid-axis-frame", style: { height: frameHeight } }))); 13122 }; 13123 /* Table Component Render Methods 13124 ------------------------------------------------------------------------------------------------------------------*/ 13125 // only a one-way height sync. we don't send the axis inner-content height to the DayGrid, 13126 // but DayGrid still needs to have classNames on inner elements in order to measure. 13127 _this.renderTableRowAxis = function (rowHeight) { 13128 var _a = _this.context, options = _a.options, viewApi = _a.viewApi; 13129 var hookProps = { 13130 text: options.allDayText, 13131 view: viewApi, 13132 }; 13133 return ( 13134 // TODO: make reusable hook. used in list view too 13135 createElement(RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner$1, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, "aria-hidden": true, className: [ 13136 'fc-timegrid-axis', 13137 'fc-scrollgrid-shrink', 13138 ].concat(classNames).join(' ') }, 13139 createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame' + (rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : ''), style: { height: rowHeight } }, 13140 createElement("span", { className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner", ref: innerElRef }, innerContent)))); })); 13141 }; 13142 _this.handleSlatCoords = function (slatCoords) {
13143 _this.setState({ slatCoords: slatCoords }); 13144 }; 13145 return _this; 13146 } 13147 // rendering 13148 // ---------------------------------------------------------------------------------------------------- 13149 TimeColsView.prototype.renderSimpleLayout = function (headerRowContent, allDayContent, timeContent) { 13150 var _a = this, context = _a.context, props = _a.props; 13151 var sections = []; 13152 var stickyHeaderDates = getStickyHeaderDates(context.options); 13153 if (headerRowContent) { 13154 sections.push({ 13155 type: 'header', 13156 key: 'header', 13157 isSticky: stickyHeaderDates, 13158 chunk: { 13159 elRef: this.headerElRef, 13160 tableClassName: 'fc-col-header', 13161 rowContent: headerRowContent, 13162 }, 13163 }); 13164 } 13165 if (allDayContent) { 13166 sections.push({ 13167 type: 'body', 13168 key: 'all-day', 13169 chunk: { content: allDayContent }, 13170 }); 13171 sections.push({ 13172 type: 'body', 13173 key: 'all-day-divider', 13174 outerContent: ( // TODO: rename to cellContent so don't need to define <tr>? 13175 createElement("tr", { role: "presentation", className: "fc-scrollgrid-section" }, 13176 createElement("td", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))), 13177 }); 13178 } 13179 sections.push({ 13180 type: 'body', 13181 key: 'body', 13182 liquid: true, 13183 expandRows: Boolean(context.options.expandRows), 13184 chunk: { 13185 scrollerElRef: this.scrollerElRef, 13186 content: timeContent, 13187 }, 13188 }); 13189 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef }, 13190 createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [{ width: 'shrink' }], sections: sections }))); })); 13191 }; 13192 TimeColsView.prototype.renderHScrollLayout = function (headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) { 13193 var _this = this; 13194 var ScrollGrid = this.context.pluginHooks.scrollGridImpl; 13195 if (!ScrollGrid) { 13196 throw new Error('No ScrollGrid implementation'); 13197 } 13198 var _a = this, context = _a.context, props = _a.props; 13199 var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options); 13200 var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options); 13201 var sections = []; 13202 if (headerRowContent) { 13203 sections.push({ 13204 type: 'header', 13205 key: 'header', 13206 isSticky: stickyHeaderDates, 13207 syncRowHeights: true, 13208 chunks: [ 13209 { 13210 key: 'axis', 13211 rowContent: function (arg) { return (createElement("tr", { role: "presentation" }, _this.renderHeadAxis('day', arg.rowSyncHeights[0]))); }, 13212 }, 13213 { 13214 key: 'cols', 13215 elRef: this.headerElRef, 13216 tableClassName: 'fc-col-header', 13217 rowContent: headerRowContent, 13218 }, 13219 ], 13220 }); 13221 } 13222 if (allDayContent) { 13223 sections.push({ 13224 type: 'body', 13225 key: 'all-day', 13226 syncRowHeights: true, 13227 chunks: [ 13228 { 13229 key: 'axis', 13230 rowContent: function (contentArg) { return (createElement("tr", { role: "presentation" }, _this.renderTableRowAxis(contentArg.rowSyncHeights[0]))); }, 13231 }, 13232 { 13233 key: 'cols', 13234 content: allDayContent, 13235 }, 13236 ], 13237 }); 13238 sections.push({ 13239 key: 'all-day-divider', 13240 type: 'body', 13241 outerContent: ( // TODO: rename to cellContent so don't need to define <tr>? 13242 createElement("tr", { role: "presentation", className: "fc-scrollgrid-section" }, 13243 createElement("td", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))), 13244 }); 13245 } 13246 var isNowIndicator = context.options.nowIndicator; 13247 sections.push({ 13248 type: 'body', 13249 key: 'body', 13250 liquid: true, 13251 expandRows: Boolean(context.options.expandRows), 13252 chunks: [ 13253 { 13254 key: 'axis', 13255 content: function (arg) { return ( 13256 // TODO: make this now-indicator arrow more DRY with TimeColsContent 13257 createElement("div", { className: "fc-timegrid-axis-chunk" }, 13258 createElement("table", { "aria-hidden": true, style: { height: arg.expandRows ? arg.clientHeight : '' } }, 13259 arg.tableColGroupNode, 13260 createElement("tbody", null, 13261 createElement(TimeBodyAxis, { slatMetas: slatMetas }))), 13262 createElement("div", { className: "fc-timegrid-now-indicator-container" }, 13263 createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, function (nowDate) { 13264 var nowIndicatorTop = isNowIndicator && 13265 slatCoords && 13266 slatCoords.safeComputeTop(nowDate); // might return void 13267 if (typeof nowIndicatorTop === 'number') { 13268 return (createElement(NowIndicatorRoot, { isAxis: true, date: nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); })); 13269 } 13270 return null; 13271 })))); }, 13272 }, 13273 { 13274 key: 'cols', 13275 scrollerElRef: this.scrollerElRef, 13276 content: timeContent, 13277 }, 13278 ], 13279 }); 13280 if (stickyFooterScrollbar) { 13281 sections.push({ 13282 key: 'footer', 13283 type: 'footer', 13284 isSticky: true, 13285 chunks: [ 13286 { 13287 key: 'axis', 13288 content: renderScrollShim, 13289 }, 13290 { 13291 key: 'cols', 13292 content: renderScrollShim, 13293 }, 13294 ], 13295 }); 13296 } 13297 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].
13297concat(classNames).join(' '), ref: rootElRef }, 13298 createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: false, colGroups: [ 13299 { width: 'shrink', cols: [{ width: 'shrink' }] }, 13300 { cols: [{ span: colCnt, minWidth: dayMinWidth }] }, 13301 ], sections: sections }))); })); 13302 }; 13303 /* Dimensions 13304 ------------------------------------------------------------------------------------------------------------------*/ 13305 TimeColsView.prototype.getAllDayMaxEventProps = function () { 13306 var _a = this.context.options, dayMaxEvents = _a.dayMaxEvents, dayMaxEventRows = _a.dayMaxEventRows; 13307 if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto? 13308 dayMaxEvents = undefined; 13309 dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number 13310 } 13311 return { dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows }; 13312 }; 13313 return TimeColsView; 13314 }(DateComponent)); 13315 function renderAllDayInner$1(hookProps) { 13316 return hookProps.text; 13317 } 13318 13319 var TimeColsSlatsCoords = /** @class */ (function () { 13320 function TimeColsSlatsCoords(positions, dateProfile, slotDuration) { 13321 this.positions = positions; 13322 this.dateProfile = dateProfile; 13323 this.slotDuration = slotDuration; 13324 } 13325 TimeColsSlatsCoords.prototype.safeComputeTop = function (date) { 13326 var dateProfile = this.dateProfile; 13327 if (rangeContainsMarker(dateProfile.currentRange, date)) { 13328 var startOfDayDate = startOfDay(date); 13329 var timeMs = date.valueOf() - startOfDayDate.valueOf(); 13330 if (timeMs >= asRoughMs(dateProfile.slotMinTime) && 13331 timeMs < asRoughMs(dateProfile.slotMaxTime)) { 13332 return this.computeTimeTop(createDuration(timeMs)); 13333 } 13334 } 13335 return null; 13336 }; 13337 // Computes the top coordinate, relative to the bounds of the grid, of the given date. 13338 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. 13339 TimeColsSlatsCoords.prototype.computeDateTop = function (when, startOfDayDate) { 13340 if (!startOfDayDate) { 13341 startOfDayDate = startOfDay(when); 13342 } 13343 return this.computeTimeTop(createDuration(when.valueOf() - startOfDayDate.valueOf())); 13344 }; 13345 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). 13346 // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform. 13347 // Eventually allow computation with arbirary slat dates. 13348 TimeColsSlatsCoords.prototype.computeTimeTop = function (duration) { 13349 var _a = this, positions = _a.positions, dateProfile = _a.dateProfile; 13350 var len = positions.els.length; 13351 // floating-point value of # of slots covered 13352 var slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / asRoughMs(this.slotDuration); 13353 var slatIndex; 13354 var slatRemainder; 13355 // compute a floating-point number for how many slats should be progressed through. 13356 // from 0 to number of slats (inclusive) 13357 // constrained because slotMinTime/slotMaxTime might be customized. 13358 slatCoverage = Math.max(0, slatCoverage); 13359 slatCoverage = Math.min(len, slatCoverage); 13360 // an integer index of the furthest whole slat 13361 // from 0 to number slats (*exclusive*, so len-1) 13362 slatIndex = Math.floor(slatCoverage); 13363 slatIndex = Math.min(slatIndex, len - 1); 13364 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition. 13365 // could be 1.0 if slatCoverage is covering *all* the slots 13366 slatRemainder = slatCoverage - slatIndex; 13367 return positions.tops[slatIndex] + 13368 positions.getHeight(slatIndex) * slatRemainder; 13369 }; 13370 return TimeColsSlatsCoords; 13371 }()); 13372 13373 var TimeColsSlatsBody = /** @class */ (function (_super) { 13374 __extends(TimeColsSlatsBody, _super); 13375 function TimeColsSlatsBody() { 13376 return _super !== null && _super.apply(this, arguments) || this; 13377 } 13378 TimeColsSlatsBody.prototype.render = function () { 13379 var _a = this, props = _a.props, context = _a.context; 13380 var options = context.options; 13381 var slatElRefs = props.slatElRefs; 13382 return (createElement("tbody", null, props.slatMetas.map(function (slatMeta, i) { 13383 var hookProps = { 13384 time: slatMeta.time, 13385 date: context.dateEnv.toDate(slatMeta.date), 13386 view: context.viewApi, 13387 }; 13388 var classNames = [ 13389 'fc-timegrid-slot', 13390 'fc-timegrid-slot-lane', 13391 slatMeta.isLabeled ? '' : 'fc-timegrid-slot-minor', 13392 ]; 13393 return (createElement("tr", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) }, 13394 props.axis && (createElement(TimeColsAxisCell, __assign({}, slatMeta))), 13395 createElement(RenderHook, { hookProps: hookProps, classNames: options.slotLaneClassNames, content: options.slotLaneContent, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: classNames.c
13395oncat(customClassNames).join(' '), "data-time": slatMeta.isoTimeStr }, innerContent)); }))); 13396 }))); 13397 }; 13398 return TimeColsSlatsBody; 13399 }(BaseComponent)); 13400 13401 /* 13402 for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL. 13403 */ 13404 var TimeColsSlats = /** @class */ (function (_super) { 13405 __extends(TimeColsSlats, _super); 13406 function TimeColsSlats() { 13407 var _this = _super !== null && _super.apply(this, arguments) || this; 13408 _this.rootElRef = createRef(); 13409 _this.slatElRefs = new RefMap(); 13410 return _this; 13411 } 13412 TimeColsSlats.prototype.render = function () { 13413 var _a = this, props = _a.props, context = _a.context; 13414 return (createElement("div", { ref: this.rootElRef, className: "fc-timegrid-slots" }, 13415 createElement("table", { "aria-hidden": true, className: context.theme.getClass('table'), style: { 13416 minWidth: props.tableMinWidth, 13417 width: props.clientWidth, 13418 height: props.minHeight, 13419 } }, 13420 props.tableColGroupNode /* relies on there only being a single <col> for the axis */, 13421 createElement(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas })))); 13422 }; 13423 TimeColsSlats.prototype.componentDidMount = function () { 13424 this.updateSizing(); 13425 }; 13426 TimeColsSlats.prototype.componentDidUpdate = function () { 13427 this.updateSizing(); 13428 }; 13429 TimeColsSlats.prototype.componentWillUnmount = function () { 13430 if (this.props.onCoords) { 13431 this.props.onCoords(null); 13432 } 13433 }; 13434 TimeColsSlats.prototype.updateSizing = function () { 13435 var _a = this, context = _a.context, props = _a.props; 13436 if (props.onCoords && 13437 props.clientWidth !== null // means sizing has stabilized 13438 ) { 13439 var rootEl = this.rootElRef.current; 13440 if (rootEl.offsetHeight) { // not hidden by css 13441 props.onCoords(new TimeColsSlatsCoords(new PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration)); 13442 } 13443 } 13444 }; 13445 return TimeColsSlats; 13446 }(BaseComponent)); 13447 function collectSlatEls(elMap, slatMetas) { 13448 return slatMetas.map(function (slatMeta) { return elMap[slatMeta.key]; }); 13449 } 13450 13451 function splitSegsByCol(segs, colCnt) { 13452 var segsByCol = []; 13453 var i; 13454 for (i = 0; i < colCnt; i += 1) { 13455 segsByCol.push([]); 13456 } 13457 if (segs) { 13458 for (i = 0; i < segs.length; i += 1) { 13459 segsByCol[segs[i].col].push(segs[i]); 13460 } 13461 } 13462 return segsByCol; 13463 } 13464 function splitInteractionByCol(ui, colCnt) { 13465 var byRow = []; 13466 if (!ui) { 13467 for (var i = 0; i < colCnt; i += 1) { 13468 byRow[i] = null; 13469 } 13470 } 13471 else { 13472 for (var i = 0; i < colCnt; i += 1) { 13473 byRow[i] = { 13474 affectedInstances: ui.affectedInstances, 13475 isEvent: ui.isEvent, 13476 segs: [], 13477 }; 13478 } 13479 for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) { 13480 var seg = _a[_i]; 13481 byRow[seg.col].segs.push(seg); 13482 } 13483 } 13484 return byRow; 13485 } 13486 13487 var TimeColMoreLink = /** @class */ (function (_super) { 13488 __extends(TimeColMoreLink, _super); 13489 function TimeColMoreLink() { 13490 var _this = _super !== null && _super.apply(this, arguments) || this; 13491 _this.rootElRef = createRef(); 13492 return _this; 13493 } 13494 TimeColMoreLink.prototype.render = function () { 13495 var _this = this; 13496 var props = this.props; 13497 return (createElement(MoreLinkRoot, { allDayDate: null, moreCnt: props.hiddenSegs.length, allSegs: props.hiddenSegs, hiddenSegs: props.hiddenSegs, al
13497ignmentElRef: this.rootElRef, defaultContent: renderMoreLinkInner, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, todayRange: props.todayRange, popoverContent: function () { return renderPlainFgSegs(props.hiddenSegs, props); } }, function (rootElRef, classNames, innerElRef, innerContent, handleClick, title, isExpanded, popoverId) { return (createElement("a", { ref: function (el) { 13498 setRef(rootElRef, el); 13499 setRef(_this.rootElRef, el); 13500 }, className: ['fc-timegrid-more-link'].concat(classNames).join(' '), style: { top: props.top, bottom: props.bottom }, onClick: handleClick, title: title, "aria-expanded": isExpanded, "aria-controls": popoverId }, 13501 createElement("div", { ref: innerElRef, className: "fc-timegrid-more-link-inner fc-sticky" }, innerContent))); })); 13502 }; 13503 return TimeColMoreLink; 13504 }(BaseComponent)); 13505 function renderMoreLinkInner(props) { 13506 return props.shortText; 13507 } 13508 13509 // segInputs assumed sorted 13510 function buildPositioning(segInputs, strictOrder, maxStackCnt) { 13511 var hierarchy = new SegHierarchy(); 13512 if (strictOrder != null) { 13513 hierarchy.strictOrder = strictOrder; 13514 } 13515 if (maxStackCnt != null) { 13516 hierarchy.maxStackCnt = maxStackCnt; 13517 } 13518 var hiddenEntries = hierarchy.addSegs(segInputs); 13519 var hiddenGroups = groupIntersectingEntries(hiddenEntries); 13520 var web = buildWeb(hierarchy); 13521 web = stretchWeb(web, 1); // all levelCoords/thickness will have 0.0-1.0 13522 var segRects = webToRects(web); 13523 return { segRects: segRects, hiddenGroups: hiddenGroups }; 13524 } 13525 function buildWeb(hierarchy) { 13526 var entriesByLevel = hierarchy.entriesByLevel; 13527 var buildNode = cacheable(function (level, lateral) { return level + ':' + lateral; }, function (level, lateral) { 13528 var siblingRange = findNextLevelSegs(hierarchy, level, lateral); 13529 var nextLevelRes = buildNodes(siblingRange, buildNode); 13530 var entry = entriesByLevel[level][lateral]; 13531 return [ 13532 __assign(__assign({}, entry), { nextLevelNodes: nextLevelRes[0] }), 13533 entry.thickness + nextLevelRes[1], // the pressure builds 13534 ]; 13535 }); 13536 return buildNodes(entriesByLevel.length 13537 ? { level: 0, lateralStart: 0, lateralEnd: entriesByLevel[0].length } 13538 : null, buildNode)[0]; 13539 } 13540 function buildNodes(siblingRange, buildNode) { 13541 if (!siblingRange) { 13542 return [[], 0]; 13543 } 13544 var level = siblingRange.level, lateralStart = siblingRange.lateralStart, lateralEnd = siblingRange.lateralEnd; 13545 var lateral = lateralStart; 13546 var pairs = []; 13547 while (lateral < lateralEnd) { 13548 pairs.push(buildNode(level, lateral)); 13549 lateral += 1; 13550 } 13551 pairs.sort(cmpDescPressures); 13552 return [ 13553 pairs.map(extractNode), 13554 pairs[0][1], // first item's pressure 13555 ]; 13556 } 13557 function cmpDescPressures(a, b) { 13558 return b[1] - a[1]; 13559 } 13560 function extractNode(a) { 13561 return a[0]; 13562 } 13563 function findNextLevelSegs(hierarchy, subjectLevel, subjectLateral) { 13564 var levelCoords = hierarchy.levelCoords, entriesByLevel = hierarchy.entriesByLevel; 13565 var subjectEntry = entriesByLevel[subjectLevel][subjectLateral]; 13566 var afterSubject = levelCoords[subjectLevel] + subjectEntry.thickness; 13567 var levelCnt = levelCoords.length; 13568 var level = subjectLevel; 13569 // skip past levels that are too high up 13570 for (; level < levelCnt && levelCoords[level] < afterSubject; level += 1) 13571 ; // do nothing 13572 for (; level < levelCnt; level += 1) { 13573 var entries = entriesByLevel[level]; 13574 var entry = void 0; 13575 var searchIndex = binarySearch(entries, subjectEntry.span.start, getEntrySpanEnd); 13576 var lateralStart = searchIndex[0] + searchIndex[1]; // if exact match (which doesn't collide), go to next one 13577 var lateralEnd = lateralStart; 13578 while ( // loop through entries that horizontally intersect 13579 (entry = entries[lateralEnd]) && // but not past the whole seg list 13580 entry.span.start < subjectEntry.span.end) { 13581 lateralEnd += 1; 13582 } 13583 if (lateralStart < lateralEnd) { 13584 return { level: level, lateralStart: lateralStart, lateralEnd: lateralEnd }; 13585 } 13586 } 13587 return null; 13588 } 13589 function stretchWeb(topLevelNodes, totalThickness) { 13590 var stretchNode = cacheable(function (node, startCoord, prevThickness) { return buildEntryKey(node); }, function (node, startCoord, prevThickness) { 13591 var nextLevelNodes = node.nextLevelNodes, thickness = node.thickness; 13592 var allThickness = thickness + prevThickness; 13593 var thicknessFraction = thickness / allThickness; 13594 var endCoord; 13595 var newChildren = []; 13596 if (!nextLevelNodes.length) { 13597 endCoord = totalThickness; 13598 } 13599 else { 13600 for (var _i = 0, nextLevelNodes_1 = nextLevelNodes; _i < nextLevelNodes_1.length; _i++) { 13601 var childNode = nextLevelNodes_1[_i]; 13602 if (endCoord === undefined) { 13603 var res = stretchNode(childNode, startCoord, allThickness); 13604 endCoord = res[0]; 13605 newChildren.push(res[1]); 13606 } 13607 else { 13608 var res = stretchNode(childNode, endCoord, 0); 13609 newChildren.push(res[1]); 13610 } 13611 } 13612 } 13613 var newThickness = (endCoord - startCoord) * thicknessFraction; 13614 return [endCoord - newThickness, __assign(__assign({}, node), { thickness: newThickness, nextLevelNodes: newChildren })]; 13615 }); 13616 return topLevelNodes.map(function (node) { return stretchNode(node,
136160, 0)[1]; }); 13617 } 13618 // not sorted in any particular order 13619 function webToRects(topLevelNodes) { 13620 var rects = []; 13621 var processNode = cacheable(function (node, levelCoord, stackDepth) { return buildEntryKey(node); }, function (node, levelCoord, stackDepth) { 13622 var rect = __assign(__assign({}, node), { levelCoord: levelCoord, 13623 stackDepth: stackDepth, stackForward: 0 }); 13624 rects.push(rect); 13625 return (rect.stackForward = processNodes(node.nextLevelNodes, levelCoord + node.thickness, stackDepth + 1) + 1); 13626 }); 13627 function processNodes(nodes, levelCoord, stackDepth) { 13628 var stackForward = 0; 13629 for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) { 13630 var node = nodes_1[_i]; 13631 stackForward = Math.max(processNode(node, levelCoord, stackDepth), stackForward); 13632 } 13633 return stackForward; 13634 } 13635 processNodes(topLevelNodes, 0, 0); 13636 return rects; // TODO: sort rects by levelCoord to be consistent with toRects? 13637 } 13638 // TODO: move to general util 13639 function cacheable(keyFunc, workFunc) { 13640 var cache = {}; 13641 return function () { 13642 var args = []; 13643 for (var _i = 0; _i < arguments.length; _i++) { 13644 args[_i] = arguments[_i]; 13645 } 13646 var key = keyFunc.apply(void 0, args); 13647 return (key in cache) 13648 ? cache[key] 13649 : (cache[key] = workFunc.apply(void 0, args)); 13650 }; 13651 } 13652 13653 function computeSegVCoords(segs, colDate, slatCoords, eventMinHeight) { 13654 if (slatCoords === void 0) { slatCoords = null; } 13655 if (eventMinHeight === void 0) { eventMinHeight = 0; } 13656 var vcoords = []; 13657 if (slatCoords) { 13658 for (var i = 0; i < segs.length; i += 1) { 13659 var seg = segs[i]; 13660 var spanStart = slatCoords.computeDateTop(seg.start, colDate); 13661 var spanEnd = Math.max(spanStart + (eventMinHeight || 0), // :( 13662 slatCoords.computeDateTop(seg.end, colDate)); 13663 vcoords.push({ 13664 start: Math.round(spanStart), 13665 end: Math.round(spanEnd), // 13666 }); 13667 } 13668 } 13669 return vcoords; 13670 } 13671 function computeFgSegPlacements(segs, segVCoords, // might not have for every seg 13672 eventOrderStrict, eventMaxStack) { 13673 var segInputs = []; 13674 var dumbSegs = []; // segs without coords 13675 for (var i = 0; i < segs.length; i += 1) { 13676 var vcoords = segVCoords[i]; 13677 if (vcoords) { 13678 segInputs.push({ 13679 index: i, 13680 thickness: 1, 13681 span: vcoords, 13682 }); 13683 } 13684 else { 13685 dumbSegs.push(segs[i]); 13686 } 13687 } 13688 var _a = buildPositioning(segInputs, eventOrderStrict, eventMaxStack), segRects = _a.segRects, hiddenGroups = _a.hiddenGroups; 13689 var segPlacements = []; 13690 for (var _i = 0, segRects_1 = segRects; _i < segRects_1.length; _i++) { 13691 var segRect = segRects_1[_i]; 13692 segPlacements.push({ 13693 seg: segs[segRect.index], 13694 rect: segRect, 13695 }); 13696 } 13697 for (var _b = 0, dumbSegs_1 = dumbSegs; _b < dumbSegs_1.length; _b++) { 13698 var dumbSeg = dumbSegs_1[_b]; 13699 segPlacements.push({ seg: dumbSeg, rect: null }); 13700 } 13701 return { segPlacements: segPlacements, hiddenGroups: hiddenGroups }; 13702 } 13703 13704 var DEFAULT_TIME_FORMAT$1 = createFormatter({ 13705 hour: 'numeric', 13706 minute: '2-digit', 13707 meridiem: false, 13708 }); 13709 var TimeColEvent = /** @class */ (function (_super) { 13710 __extends(TimeColEvent, _super); 13711 function TimeColEvent() { 13712 return _super !== null && _super.apply(this, arguments) || this; 13713 } 13714 TimeColEvent.prototype.render = function () { 13715 var classNames = [ 13716 'fc-timegrid-event', 13717 'fc-v-event', 13718 ]; 13719 if (this.props.isShort) { 13720 classNames.push('fc-timegrid-event-short'); 13721 } 13722 return (createElement(StandardEvent, __assign({}, this.props, { defaultTimeFormat: DEFAULT_TIME_FORMAT$1, extraClassNames: classNames }))); 13723 }; 13724 return TimeColEvent; 13725 }(BaseComponent)); 13726 13727 var TimeColMisc = /** @class */ (function (_super) { 13728 __extends(TimeColMisc, _super); 13729 function TimeColMisc() { 13730 return _super !== null && _super.apply(this, arguments) || this; 13731 } 13732 TimeColMisc.prototype.render = function () { 13733 var props = this.props; 13734 return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (innerElRef, innerContent) { return (innerContent && 13735 createElement("div", { className: "fc-timegrid-col-misc", ref: innerElRef }, innerContent)); })); 13736 }; 13737 return TimeColMisc; 13738 }(BaseComponent)); 13739 13740 var TimeCol = /** @class */ (function (_super) { 13741 __extends(TimeCol, _super); 13742 function TimeCol() { 13743 var _this = _super !== null && _super.apply(this, arguments) || this; 13744 _this.sortEventSegs = memoize(sortEventSegs); 13745 return _this; 13746 } 13747 // TODO: memoize event-placement? 13748 TimeCol.prototype.render = function () { 13749 var _this = this; 13750 var _a = this, props = _a.props, context = _a.context; 13751 var isSelectMirror = context.options.selectMirror; 13752 var mirrorSegs = (props.eventDrag && props.eventDrag.segs) || 13753 (props.eventResize && props.eventResize.segs) || 13754 (isSelectMirror && props.dateSelectionSegs) || 13755 []; 13756 var interactionAffectedInstances = // TODO: messy way to compute this 13757 (props.eventDrag && props.eventDrag.affectedInstances) || 13758 (props.eventResize && props.eventResize.affectedInstances) || 13759 {}; 13760 var sortedFgSegs = this.sortEventSegs(props.fgEventSegs, context.options.eventOrder); 13761 return (createElement(DayCellRoot, { elRef: props.elRef, date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (rootElRef, classNames, dataAttrs) { return (createElement("td", __assign({ ref: rootElRef, role: "gridcell", className: ['fc-timegrid-col'].concat(classNames, props.extraClassNames || []).join(' ') }, dataAttrs, props.extraDataAttrs), 13762 createElement("div", { className: "fc-timegrid-col-frame" }, 13763 createElement("div", { className: "fc-timegrid-col-bg" }, 13764 _this.renderFillSegs(props.businessHourSegs, 'non-business'), 13765 _this.renderFillSegs(props.bgEventSegs, 'bg-event'), 13766 _this.renderFillSegs(props.dateSelectionSegs, 'highlight')), 13767 createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(sortedFgSegs, interactionAffectedInstances, false, false, false)), 13768 createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror))), 13769 createElement("div", { className: "fc-timegrid-now-indicator-container" }, _this.renderNowIndicator(props.nowIndicatorSegs)), 13770 createElement(TimeColMisc, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps })))); })); 13771 }; 13772 TimeCol.prototype.renderFgSegs = function (sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting) { 13773 var props = this.props; 13774 if (props.forPrint) { 13775 return renderPlainFgSegs(sortedFgSegs, props); 13776 } 13777 return this.renderPositionedFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting); 13778 }; 13779 TimeCol.prototype.renderPositionedFgSegs = function (segs, // if not mirror, needs to be sorted 13780 segIsInvisible, isDragging, isResizing, isDateSelecting) { 13781 var _this = this; 13782 var _a = this.context.options, eventMaxStack = _a.eventMaxStack, eventShortHeight = _a.eventShortHeight, eventOrderStrict = _a.eventOrderStrict, eventMinHeight = _a.eventMinHeight; 13783 var _b = this.props, date = _b.date, slatCoords = _b.slatCoords, eventSelection = _b.eventSelection, todayRange = _b.todayRange, nowDate = _b.nowDate; 13784 var isMirror = isDragging || isResizing || isDateSelecting; 13785 var segVCoords = computeSegVCoords(segs, date, slatCoords, eventMinHeight); 13786 var _c = computeFgSegPlacements(segs, segVCoords, eventOrderStrict, eventMaxStack), segPlacements = _c.segPlacements, hiddenGroups = _c.hiddenGroups; 13787 return (createElement(Fragment, null, 13788 this.renderHiddenGroups(hiddenGroups, segs), 13789 segPlacements.map(function (segPlacement) { 13790 var seg = segPlacement.seg, rect = segPlacement.rect; 13791 var instanceId = seg.eventRange.instance.instanceId; 13792 var isVisible = isMirror || Boolean(!segIsInvisible[instanceId] && rect); 13793 var vStyle = computeSegVStyle(rect && rect.span); 13794 var hStyle = (!isMirror && rect) ? _this.computeSegHStyle(rect) : { left: 0, right: 0 }; 13795 var isInset = Boolean(rect) && rect.stackForward > 0;
13796 var isShort = Boolean(rect) && (rect.span.end - rect.span.start) < eventShortHeight; // look at other places for this problem 13797 return (createElement("div", { className: 'fc-timegrid-event-harness' + 13798 (isInset ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: __assign(__assign({ visibility: isVisible ? '' : 'hidden' }, vStyle), hStyle) }, 13799 createElement(TimeColEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, isShort: isShort }, getSegMeta(seg, todayRange, nowDate))))); 13800 }))); 13801 }; 13802 // will already have eventMinHeight applied because segInputs already had it 13803 TimeCol.prototype.renderHiddenGroups = function (hiddenGroups, segs) { 13804 var _a = this.props, extraDateSpan = _a.extraDateSpan, dateProfile = _a.dateProfile, todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize; 13805 return (createElement(Fragment, null, hiddenGroups.map(function (hiddenGroup) { 13806 var positionCss = computeSegVStyle(hiddenGroup.span); 13807 var hiddenSegs = compileSegsFromEntries(hiddenGroup.entries, segs); 13808 return (createElement(TimeColMoreLink, { key: buildIsoString(computeEarliestSegStart(hiddenSegs)), hiddenSegs: hiddenSegs, top: positionCss.top, bottom: positionCss.bottom, extraDateSpan: extraDateSpan, dateProfile: dateProfile, todayRange: todayRange, nowDate: nowDate, eventSelection: eventSelection, eventDrag: eventDrag, eventResize: eventResize })); 13809 }))); 13810 }; 13811 TimeCol.prototype.renderFillSegs = function (segs, fillType) { 13812 var _a = this, props = _a.props, context = _a.context; 13813 var segVCoords = computeSegVCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight); // don't assume all populated 13814 var children = segVCoords.map(function (vcoords, i) { 13815 var seg = segs[i]; 13816 return (createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-timegrid-bg-harness", style: computeSegVStyle(vcoords) }, fillType === 'bg-event' ? 13817 createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, props.todayRange, props.nowDate))) : 13818 renderFill(fillType))); 13819 }); 13820 return createElement(Fragment, null, children); 13821 }; 13822 TimeCol.prototype.renderNowIndicator = function (segs) { 13823 var _a = this.props, slatCoords = _a.slatCoords, date = _a.date; 13824 if (!slatCoords) { 13825 return null; 13826 } 13827 return segs.map(function (seg, i) { return (createElement(NowIndicatorRoot, { isAxis: false, date: date, 13828 // key doesn't matter. will only ever be one 13829 key: i }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-line'].concat(classNames).join(' '), style: { top: slatCoords.computeDateTop(seg.start, date) } }, innerContent)); })); }); 13830 }; 13831 TimeCol.prototype.computeSegHStyle = function (segHCoords) { 13832 var _a = this.context, isRtl = _a.isRtl, options = _a.options; 13833 var shouldOverlap = options.slotEventOverlap; 13834 var nearCoord = segHCoords.levelCoord; // the left side if LTR. the right side if RTL. floating-point 13835 var farCoord = segHCoords.levelCoord + segHCoords.thickness; // the right side if LTR. the left side if RTL. floating-point 13836 var left; // amount of space from left edge, a fraction of the total width 13837 var right; // amount of space from right edge, a fraction of the total width 13838 if (shouldOverlap) { 13839 // double the width, but don't go beyond the maximum forward coordinate (1.0) 13840 farCoord = Math.min(1, nearCoord + (farCoord - nearCoord) * 2); 13841 } 13842 if (isRtl) { 13843 left = 1 - farCoord; 13844 right = nearCoord; 13845 } 13846 else { 13847 left = nearCoord; 13848 right = 1 - farCoord; 13849 } 13850 var props = { 13851 zIndex: segHCoords.stackDepth + 1, 13852 left: left * 100 + '%', 13853 right: right * 100 + '%', 13854 }; 13855 if (shouldOverlap && !segHCoords.stackForward) { 13856 // add padding to the edge so that forward stacked events don't cover the resizer's icon 13857 props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width 13858 } 13859 return props; 13860 }; 13861 return TimeCol; 13862 }(BaseComponent)); 13863 function renderPlainFgSegs(sortedFgSegs, _a) { 13864 var todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize; 13865 var hiddenInstances = (eventDrag ? eventDrag.affectedInstances : null) || 13866 (eventResize ? eventResize.affectedInstances : null) || 13867 {}; 13868 return (createElement(Fragment, null, sortedFgSegs.map(function (seg) { 13869 var instanceId = seg.eventRange.instance.instanceId; 13870 return (createElement("div", { key: instanceId, style: { visibility: hiddenInstances[instanceId] ? 'hidden' : '' } }, 13871 createElement(TimeColEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === eventSelection, isShort: false }, getSegMeta(seg, todayRange, nowDate))))); 13872 }))); 13873 } 13874 function computeSegVStyle(segVCoords) { 13875 if (!segVCoords) { 13876 return { top: '', bottom: '' }; 13877 } 13878 return { 13879 top: segVCoords.start, 13880 bottom: -segVCoords.end, 13881 }; 13882 } 13883 function compileSegsFromEntries(segEntries, allSegs) { 13884 return segEntries.map(function (segEntry) { return allSegs[segEntry.index]; }); 13885 } 13886 13887 var TimeColsContent = /** @class */ (function (_super) { 13888 __extends(TimeColsContent, _super); 13889 function TimeColsContent() { 13890 var _this = _super !== null && _super.apply(this, arguments) || this; 13891 _this.splitFgEventSegs = memoize(splitSegsByCol); 13892 _this.splitBgEventSegs = memoize(splitSegsByCol); 13893 _this.splitBusinessHourSegs = memoize(splitSegsByCol); 13894 _this.splitNowIndicatorSegs = memoize(splitSegsByCol); 13895 _this.splitDateSelectionSegs = memoize(splitSegsByCol); 13896 _this.splitEventDrag = memoize(splitInteractionByCol); 13897 _this.splitEventResize = memoize(splitInteractionByCol); 13898 _this.rootElRef = createRef(); 13899 _this.cellElRefs = new RefMap(); 13900 return _this; 13901 } 13902 TimeColsContent.prototype.render = function () { 13903 var _this = this; 13904 var _a = this, props = _a.props, context = _a.context; 13905 var nowIndicatorTop = context.options.nowIndicator && 13906 props.slatCoords && 13907 props.slatCoords.safeComputeTop(props.nowDate); // might return void 13908 var colCnt = props.cells.length; 13909 var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt); 13910 var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt); 13911 var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt); 13912 var nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt); 13913 var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt); 13914 var eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt); 13915 var eventResizeByRow = this.splitEventResize(props.eventResize, colCnt); 13916 return (createElement("div", { className: "fc-timegrid-cols", ref: this.rootElRef }, 13917 createElement("table", { role: "presentation", style: { 13918 minWidth: props.tableMinWidth, 13919 width: props.clientWidth, 13920 } }, 13921 props.tableColGroupNode, 13922 createElement("tbody", { role: "presentation" }, 13923 createElement("tr", { role: "row" }, 13924 props.axis && (createElement("td", { "aria-hidden": true, className: "fc-timegrid-col fc-timegrid-axis" }, 13925 createElement("div", { className: "fc-timegrid-col-frame" }, 13926 createElement("div", { className: "fc-timegrid-now-indicator-container" }, typeof nowIndicatorTop === 'number' && (createElement(NowIndicatorRoot, { isAxis: true, date: props.nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); })))))), 13927 props.cells.map(function (cell, i) { return (createElement(TimeCol, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), dateProfile: props.dateProfile, date: cell.date, nowDate: props.nowDate, todayRange: props.todayRange, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, fgEventSegs: fgEventSegsByRow[i], bgEventSegs: bgEventSegsByRow[i], businessHourSegs: businessHourSegsByRow[i], nowIndicatorSegs: nowIndicatorSegsByRow[i], dateSelectionSegs: dateSelectionSegsByRow[i], eventDrag: eventDragByRow[i], eventResize: eventResizeByRow[i], slatCoords: props.slatCoords, eventSelection: props.eventSelection, forPrint: props.forPrint })); })))))); 13928 }; 13929 TimeColsContent.prototype.componentDidMount = function () { 13930 this.updateCoords(); 13931 }; 13932 TimeColsContent.prototype.componentDidUpdate = function () { 13933 this.updateCoords(); 13934 }; 13935 TimeColsContent.prototype.updateCoords = function () { 13936 var props = this.props; 13937 if (props.onColCoords && 13938 props.clientWidth !== null // means sizing has stabilized 13939 ) { 13940 props.onColCoords(new PositionCache(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal 13941 false)); 13942 } 13943 }; 13944 return TimeColsContent; 13945 }(BaseComponent)); 13946 function collectCellEls(elMap, cells) { 13947 return cells.map(function (cell) { return elMap[cell.key]; }); 13948 } 13949 13950 /* A component that renders one or more columns of vertical time slots 13951 ----------------------------------------------------------------------------------------------------------------------*/ 13952 var TimeCols = /** @class */ (function (_super) { 13953 __extends(TimeCols, _super); 13954 function TimeCols() { 13955 var _this = _super !== null && _super.apply(this, arguments) || this; 13956 _this.processSlotOptions = memoize(processSlotOptions); 13957 _this.state = { 13958 slatCoords: null, 13959 }; 13960 _this.handleRootEl = function (el) { 13961 if (el) { 13962 _this.context.registerInteractiveComponent(_this, { 13963 el: el, 13964 isHitComboAllowed: _this.props.isHitComboAllowed, 13965 }); 13966 } 13967 else { 13968 _this.context.unregisterInteractiveComponent(_this); 13969 } 13970 }; 13971 _this.handleScrollRequest = function (request) { 13972 var onScrollTopRequest = _this.props.onScrollTopRequest; 13973 var slatCoords = _this.state.slatCoords; 13974 if (onScrollTopRequest && slatCoords) { 13975 if (request.time) { 13976 var top_1 = slatCoords.computeTimeTop(request.time); 13977 top_1 = Math.ceil(top_1); // zoom can give weird floating-point values. rather scroll a little bit further 13978 if (top_1) { 13979 top_1 += 1; // to overcome top border that slots beyond the first have. looks better 13980 } 13981 onScrollTopRequest(top_1); 13982 } 13983 return true; 13984 } 13985 return false; 13986 }; 13987 _this.handleColCoords = function (colCoords) { 13988 _this.colCoords = colCoords; 13989 }; 13990 _this.handleSlatCoords = function (slatCoords) {
13991 _this.setState({ slatCoords: slatCoords }); 13992 if (_this.props.onSlatCoords) { 13993 _this.props.onSlatCoords(slatCoords); 13994 } 13995 }; 13996 return _this; 13997 } 13998 TimeCols.prototype.render = function () { 13999 var _a = this, props = _a.props, state = _a.state; 14000 return (createElement("div", { className: "fc-timegrid-body", ref: this.handleRootEl, style: { 14001 // these props are important to give this wrapper correct dimensions for interactions 14002 // TODO: if we set it here, can we avoid giving to inner tables? 14003 width: props.clientWidth, 14004 minWidth: props.tableMinWidth, 14005 } }, 14006 createElement(TimeColsSlats, { axis: props.axis, dateProfile: props.dateProfile, slatMetas: props.slatMetas, clientWidth: props.clientWidth, minHeight: props.expandRows ? props.clientHeight : '', tableMinWidth: props.tableMinWidth, tableColGroupNode: props.axis ? props.tableColGroupNode : null /* axis depends on the colgroup's shrinking */, onCoords: this.handleSlatCoords }), 14007 createElement(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bg
14007EventSegs, fgEventSegs: props.fgEventSegs, dateSelectionSegs: props.dateSelectionSegs, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange, nowDate: props.nowDate, nowIndicatorSegs: props.nowIndicatorSegs, clientWidth: props.clientWidth, tableMinWidth: props.tableMinWidth, tableColGroupNode: props.tableColGroupNode, slatCoords: state.slatCoords, onColCoords: this.handleColCoords, forPrint: props.forPrint }))); 14008 }; 14009 TimeCols.prototype.componentDidMount = function () { 14010 this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest); 14011 }; 14012 TimeCols.prototype.componentDidUpdate = function (prevProps) { 14013 this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile); 14014 }; 14015 TimeCols.prototype.componentWillUnmount = function () { 14016 this.scrollResponder.detach(); 14017 }; 14018 TimeCols.prototype.queryHit = function (positionLeft, positionTop) { 14019 var _a = this.context, dateEnv = _a.dateEnv, options = _a.options; 14020 var colCoords = this.colCoords; 14021 var dateProfile = this.props.dateProfile; 14022 var slatCoords = this.state.slatCoords; 14023 var _b = this.processSlotOptions(this.props.slotDuration, options.snapDuration), snapDuration = _b.snapDuration, snapsPerSlot = _b.snapsPerSlot; 14024 var colIndex = colCoords.leftToIndex(positionLeft); 14025 var slatIndex = slatCoords.positions.topToIndex(positionTop); 14026 if (colIndex != null && slatIndex != null) { 14027 var cell = this.props.cells[colIndex]; 14028 var slatTop = slatCoords.positions.tops[slatIndex]; 14029 var slatHeight = slatCoords.positions.getHeight(slatIndex); 14030 var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1 14031 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat 14032 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex; 14033 var dayDate = this.props.cells[colIndex].date; 14034 var time = addDurations(dateProfile.slotMinTime, multiplyDuration(snapDuration, snapIndex)); 14035 var start = dateEnv.add(dayDate, time); 14036 var end = dateEnv.add(start, snapDuration); 14037 return { 14038 dateProfile: dateProfile, 14039 dateSpan: __assign({ range: { start: start, end: end }, allDay: false }, cell.extraDateSpan), 14040 dayEl: colCoords.els[colIndex], 14041 rect: { 14042 left: colCoords.lefts[colIndex], 14043 right: colCoords.rights[colIndex], 14044 top: slatTop, 14045 bottom: slatTop + slatHeight, 14046 }, 14047 layer: 0, 14048 }; 14049 } 14050 return null; 14051 }; 14052 return TimeCols; 14053 }(DateComponent)); 14054 function processSlotOptions(slotDuration, snapDurationOverride) { 14055 var snapDuration = snapDurationOverride || slotDuration; 14056 var snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration); 14057 if (snapsPerSlot === null) { 14058 snapDuration = slotDuration; 14059 snapsPerSlot = 1; 14060 // TODO: say warning? 14061 } 14062 return { snapDuration: snapDuration, snapsPerSlot: snapsPerSlot }; 14063 } 14064 14065 var DayTimeColsSlicer = /** @class */ (function (_super) { 14066 __extends(DayTimeColsSlicer, _super); 14067 function DayTimeColsSlicer() { 14068 return _super !== null && _super.apply(this, arguments) || this; 14069 } 14070 DayTimeColsSlicer.prototype.sliceRange = function (range, dayRanges) { 14071 var segs = []; 14072 for (var col = 0; col < dayRanges.length; col += 1) { 14073 var segRange = intersectRanges(range, dayRanges[col]); 14074 if (segRange) { 14075 segs.push({ 14076 start: segRange.start, 14077 end: segRange.end, 14078 isStart: segRange.start.valueOf() === range.start.valueOf(), 14079 isEnd: segRange.end.valueOf() === range.end.valueOf(), 14080 col: col, 14081 }); 14082 } 14083 } 14084 return segs; 14085 }; 14086 return DayTimeColsSlicer; 14087 }(Slicer));
14088 14089 var DayTimeCols = /** @class */ (function (_super) { 14090 __extends(DayTimeCols, _super); 14091 function DayTimeCols() { 14092 var _this = _super !== null && _super.apply(this, arguments) || this; 14093 _this.buildDayRanges = memoize(buildDayRanges); 14094 _this.slicer = new DayTimeColsSlicer(); 14095 _this.timeColsRef = createRef(); 14096 return _this; 14097 } 14098 DayTimeCols.prototype.render = function () { 14099 var _this = this; 14100 var _a = this, props = _a.props, context = _a.context; 14101 var dateProfile = props.dateProfile, dayTableModel = props.dayTableModel; 14102 var isNowIndicator = context.options.nowIndicator; 14103 var dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv); 14104 // give it the first row of cells 14105 // TODO: would move this further down hierarchy, but sliceNowDate needs it 14106 return (createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' }, function (nowDate, todayRange) { return (createElement(TimeCols, __assign({ ref: _this.timeColsRef }, _this.slicer.sliceProps(props, dateProfile, null, context, dayRanges), { forPrint: props.forPrint, axis: props.axis, dateProfile: dateProfile, slatMetas: props.slatMetas, slotDuration: props.slotDuration, cells: dayTableModel.cells[0], tableColGroupNode: props.tableColGroupNode, tableMinWidth: props.tableMinWidth, clientWidth: props.clientWidth, clientHeight: props.clientHeight, expandRows: props.expandRows, nowDate: nowDate, nowIndicatorSegs: isNowIndicator && _this.slicer.sliceNowDate(nowDate, context, dayRanges), todayRange: todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords }))); })); 14107 }; 14108 return DayTimeCols; 14109 }(DateComponent)); 14110 function buildDayRanges(dayTableModel, dateProfile, dateEnv) { 14111 var ranges = []; 14112 for (var _i = 0, _a = dayTableModel.headerDates; _i < _a.length; _i++) { 14113 var date = _a[_i]; 14114 ranges.push({ 14115 start: dateEnv.add(date, dateProfile.slotMinTime), 14116 end: dateEnv.add(date, dateProfile.slotMaxTime), 14117 }); 14118 } 14119 return ranges; 14120 } 14121 14122 // potential nice values for the slot-duration and interval-duration 14123 // from largest to smallest 14124 var STOCK_SUB_DURATIONS = [ 14125 { hours: 1 }, 14126 { minutes: 30 }, 14127 { minutes: 15 }, 14128 { seconds: 30 }, 14129 { seconds: 15 }, 14130 ]; 14131 function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) { 14132 var dayStart = new Date(0); 14133 var slatTime = slotMinTime; 14134 var slatIterator = createDuration(0); 14135 var labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration); 14136 var metas = []; 14137 while (asRoughMs(slatTime) < asRoughMs(slotMaxTime)) { 14138 var date = dateEnv.add(dayStart, slatTime); 14139 var isLabeled = wholeDivideDurations(slatIterator, labelInterval) !== null; 14140 metas.push({ 14141 date: date, 14142 time: slatTime, 14143 key: date.toISOString(), 14144 isoTimeStr: formatIsoTimeString(date), 14145 isLabeled: isLabeled, 14146 }); 14147 slatTime = addDurations(slatTime, slotDuration); 14148 slatIterator = addDurations(slatIterator, slotDuration); 14149 } 14150 return metas; 14151 } 14152 // Computes an automatic value for slotLabelInterval 14153 function computeLabelInterval(slotDuration) { 14154 var i; 14155 var labelInterval; 14156 var slotsPerLabel; 14157 // find the smallest stock label interval that results in more than one slots-per-label 14158 for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i -= 1) { 14159 labelInterval = createDuration(STOCK_SUB_DURATIONS[i]); 14160 slotsPerLabel = wholeDivideDurations(labelInterval, slotDuration);
14161 if (slotsPerLabel !== null && slotsPerLabel > 1) { 14162 return labelInterval; 14163 } 14164 } 14165 return slotDuration; // fall back 14166 } 14167 14168 var DayTimeColsView = /** @class */ (function (_super) { 14169 __extends(DayTimeColsView, _super); 14170 function DayTimeColsView() { 14171 var _this = _super !== null && _super.apply(this, arguments) || this; 14172 _this.buildTimeColsModel = memoize(buildTimeColsModel); 14173 _this.buildSlatMetas = memoize(buildSlatMetas); 14174 return _this; 14175 } 14176 DayTimeColsView.prototype.render = function () { 14177 var _this = this; 14178 var _a = this.context, options = _a.options, dateEnv = _a.dateEnv, dateProfileGenerator = _a.dateProfileGenerator; 14179 var props = this.props; 14180 var dateProfile = props.dateProfile; 14181 var dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator); 14182 var splitProps = this.allDaySplitter.splitProps(props); 14183 var slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv); 14184 var dayMinWidth = options.dayMinWidth; 14185 var hasAttachedAxis = !dayMinWidth; 14186 var hasDetachedAxis = dayMinWidth; 14187 var headerContent = options.dayHeaders && (createElement(DayHeader, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null })); 14188 var allDayContent = (options.allDaySlot !== false) && (function (contentArg) { return (createElement(DayTable, __assign({}, splitProps.allDay, { dateProfile: dateProfile, dayTableModel: dayTableModel, nextDayThreshold: options.nextDayThreshold, tableMinWidth: contentArg.tableMinWidth, colGroupNode: contentArg.tableColGroupNode, renderRowIntro: hasAttachedAxis ? _this.renderTableRowAxis : null, showWeekNumbers: false, expandRows: false, headerAlignElRef: _this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }, _this.getAllDayMaxEventProps()))); }); 14189 var timeGridContent = function (contentArg) { return (createElement(DayTimeCols, __assign({}, splitProps.timed, { dayTableModel: dayTableModel, dateProfile: dateProfile, axis: hasAttachedAxis, slotDuration: options.slotDuration, slatMetas: slatMetas, forPrint: props.forPrint, tableColGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, onSlatCoords: _this.handleSlatCoords, expandRows: contentArg.expandRows, onScrollTopRequest: _this.handleScrollTopRequest }))); }; 14190 return hasDetachedAxis 14191 ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords) 14192 : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent); 14193 }; 14194 return DayTimeColsView; 14195 }(TimeColsView));
14196 function buildTimeColsModel(dateProfile, dateProfileGenerator) { 14197 var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator); 14198 return new DayTableModel(daySeries, false); 14199 } 14200 14201 var OPTION_REFINERS$2 = { 14202 allDaySlot: Boolean, 14203 }; 14204 14205 var timeGridPlugin = createPlugin({ 14206 initialView: 'timeGridWeek', 14207 optionRefiners: OPTION_REFINERS$2, 14208 views: { 14209 timeGrid: { 14210 component: DayTimeColsView, 14211 usesMinMaxTime: true, 14212 allDaySlot: true, 14213 slotDuration: '00:30:00', 14214 slotEventOverlap: true, // a bad name. confused with overlap/constraint system 14215 }, 14216 timeGridDay: { 14217 type: 'timeGrid', 14218 duration: { days: 1 }, 14219 }, 14220 timeGridWeek: { 14221 type: 'timeGrid', 14222 duration: { weeks: 1 }, 14223 }, 14224 }, 14225 }); 14226 14227 var ListViewHeaderRow = /** @class */ (function (_super) { 14228 __extends(ListViewHeaderRow, _super); 14229 function ListViewHeaderRow() { 14230 var _this = _super !== null && _super.apply(this, arguments) || this; 14231 _this.state = { 14232 textId: getUniqueDomId(), 14233 }; 14234 return _this; 14235 } 14236 ListViewHeaderRow.prototype.render = function () { 14237 var _a = this.context, theme = _a.theme, dateEnv = _a.dateEnv, options = _a.options, viewApi = _a.viewApi; 14238 var _b = this.props, cellId = _b.cellId, dayDate = _b.dayDate, todayRange = _b.todayRange; 14239 var textId = this.state.textId; 14240 var dayMeta = getDateMeta(dayDate, todayRange); 14241 // will ever be falsy? 14242 var text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : ''; 14243 // will ever be falsy? also, BAD NAME "alt" 14244 var sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : ''; 14245 var hookProps = __assign({ date: dateEnv.toDate(dayDate), view: viewApi, textId: textId, 14246 text: text, 14247 sideText: sideText, navLinkAttrs: buildNavLinkAttrs(this.context, dayDate), sideNavLinkAttrs: buildNavLinkAttrs(this.context, dayDate, 'day', false) }, dayMeta); 14248 var classNames = ['fc-list-day'].concat(getDayClassNames(dayMeta, theme)); 14249 // TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too) 14250 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInnerContent, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("tr", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-date": formatDayString(dayDate) }, 14251 createElement("th", { scope: "colgroup", colSpan: 3, id: cellId, "aria-labelledby": textId }, 14252 createElement("div", { className: 'fc-list-day-cushion ' + theme.getClass('tableCellShaded'), ref: innerElRef }, innerContent)))); })); 14253 }; 14254 return ListViewHeaderRow; 14255 }(BaseComponent)); 14256 function renderInnerContent(props) { 14257 return (createElement(Fragment, null, 14258 props.text && (createElement("a", __assign({ id: props.textId, className: "fc-list-day-text" }, props.navLinkAttrs), props.text)), 14259 props.sideText && ( /* not keyboard tabbable */createElement("a", __assign({ "aria-hidden": true, className: "fc-list-day-side-text" }, props.sideNavLinkAttrs), props.sideText)))); 14260 } 14261 14262 var DEFAULT_TIME_FORMAT = createFormatter({ 14263 hour: 'numeric', 14264 minute: '2-digit', 14265 meridiem: 'short', 14266 }); 14267 var ListViewEventRow = /** @class */ (function (_super) { 14268 __extends(ListViewEventRow, _super); 14269 function ListViewEventRow() { 14270 return _super !== null && _super.apply(this, arguments) || this; 14271 } 14272 ListViewEventRow.prototype.render = function () { 14273 var _a = this, props = _a.props, context = _a.context; 14274 var seg = props.seg, timeHeaderId = props.timeHeaderId, eventHeaderId = props.eventHeaderId, dateHeaderId = props.dateHeaderId;
14275 var timeFormat = context.options.eventTimeFormat || DEFAULT_TIME_FORMAT; 14276 return (createElement(EventRoot, { seg: seg, timeText: "" // BAD. because of all-day content 14277 , disableDragging: true, disableResizing: true, defaultContent: function () { return renderEventInnerContent(seg, context); } /* weird */, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday, isSelected: props.isSelected, isDragging: props.isDragging, isResizing: props.isResizing, isDateSelecting: props.isDateSelecting }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("tr", { className: ['fc-list-event', hookProps.event.url ? 'fc-event-forced-url' : ''].concat(classNames).join(' '), ref: rootElRef }, 14278 buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId), 14279 createElement("td", { "aria-hidden": true, className: "fc-list-event-graphic" }, 14280 createElement("span", { className: "fc-list-event-dot", style: { borderColor: hookProps.borderColor || hookProps.backgroundColor } })), 14281 createElement("td", { ref: innerElRef, headers: eventHeaderId + " " + dateHeaderId, className: "fc-list-event-title" }, innerContent))); })); 14282 }; 14283 return ListViewEventRow; 14284 }(BaseComponent)); 14285 function renderEventInnerContent(seg, context) { 14286 var interactiveAttrs = getSegAnchorAttrs(seg, context); 14287 return (createElement("a", __assign({}, interactiveAttrs), seg.eventRange.def.title)); 14288 } 14289 function buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId) { 14290 var options = context.options; 14291 if (options.displayEventTime !== false) { 14292 var eventDef = seg.eventRange.def; 14293 var eventInstance = seg.eventRange.instance; 14294 var doAllDay = false; 14295 var timeText = void 0; 14296 if (eventDef.allDay) { 14297 doAllDay = true; 14298 } 14299 else if (isMultiDayRange(seg.eventRange.range)) { // TODO: use (!isStart || !isEnd) instead? 14300 if (seg.isStart) { 14301 timeText = buildSegTimeText(seg, timeFormat, context, null, null, eventInstance.range.start, seg.end); 14302 } 14303 else if (seg.isEnd) { 14304 timeText = buildSegTimeText(seg, timeFormat, context, null, null, seg.start, eventInstance.range.end); 14305 } 14306 else { 14307 doAllDay = true; 14308 } 14309 } 14310 else { 14311 timeText = buildSegTimeText(seg, timeFormat, context); 14312 } 14313 if (doAllDay) { 14314 var hookProps = { 14315 text: context.options.allDayText, 14316 view: context.viewApi, 14317 }; 14318 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, headers: timeHeaderId + " " + dateHeaderId, className: ['fc-list-event-time'].concat(classNames).join(' ') }, innerContent)); })); 14319 } 14320 return (createElement("td", { className: "fc-list-event-time" }, timeText)); 14321 } 14322 return null; 14323 } 14324 function renderAllDayInner(hookProps) { 14325 return hookProps.text; 14326 } 14327 14328 /* 14329 Responsible for the scroller, and forwarding event-related actions into the "grid". 14330 */ 14331 var ListView = /** @class */ (function (_super) { 14332 __extends(ListView, _super); 14333 function ListView() { 14334 var _this = _super !== null && _super.apply(this, arguments) || this; 14335 _this.computeDateVars = memoize(computeDateVars); 14336 _this.eventStoreToSegs = memoize(_this._eventStoreToSegs); 14337 _this.state = { 14338 timeHeaderId: getUniqueDomId(), 14339 eventHeaderId: getUniqueDomId(), 14340 dateHeaderIdRoot: getUniqueDomId(), 14341 }; 14342 _this.setRootEl = function (rootEl) { 14343 if (rootEl) { 14344 _this.context.registerInteractiveComponent(_this, { 14345 el: rootEl, 14346 }); 14347 } 14348 else { 14349 _this.context.unregisterInteractiveComponent(_this); 14350 } 14351 }; 14352 return _this; 14353 } 14354 ListView.prototype.render = function () { 14355 var _this = this; 14356 var _a = this, props = _a.props, context = _a.context; 14357 var extraClassNames = [ 14358 'fc-list', 14359 context.theme.getClass('table'), 14360 context.options.stickyHeaderDates !== false ? 'fc-list-sticky' : '', 14361 ]; 14362 var _b = this.computeDateVars(props.dateProfile), dayDates = _b.dayDates, dayRanges = _b.dayRanges; 14363 var eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges); 14364 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.setRootEl }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: extraClassNames.c
14364oncat(classNames).join(' ') }, 14365 createElement(Scroller, { liquid: !props.isHeightAuto, overflowX: props.isHeightAuto ? 'visible' : 'hidden', overflowY: props.isHeightAuto ? 'visible' : 'auto' }, eventSegs.length > 0 ? 14366 _this.renderSegList(eventSegs, dayDates) : 14367 _this.renderEmptyMessage()))); })); 14368 }; 14369 ListView.prototype.renderEmptyMessage = function () { 14370 var _a = this.context, options = _a.options, viewApi = _a.viewApi; 14371 var hookProps = { 14372 text: options.noEventsText, 14373 view: viewApi, 14374 }; 14375 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.noEventsClassNames, content: options.noEventsContent, defaultContent: renderNoEventsInner, didMount: options.noEventsDidMount, willUnmount: options.noEventsWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { className: ['fc-list-empty'].concat(classNames).join(' '), ref: rootElRef }, 14376 createElement("div", { className: "fc-list-empty-cushion", ref: innerElRef }, innerContent))); })); 14377 }; 14378 ListView.prototype.renderSegList = function (allSegs, dayDates) { 14379 var _a = this.context, theme = _a.theme, options = _a.options; 14380 var _b = this.state, timeHeaderId = _b.timeHeaderId, eventHeaderId = _b.eventHeaderId, dateHeaderIdRoot = _b.dateHeaderIdRoot; 14381 var segsByDay = groupSegsByDay(allSegs); // sparse array 14382 return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { 14383 var innerNodes = []; 14384 for (var dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) { 14385 var daySegs = segsByDay[dayIndex]; 14386 if (daySegs) { // sparse array, so might be undefined 14387 var dayStr = formatDayString(dayDates[dayIndex]); 14388 var dateHeaderId = dateHeaderIdRoot + '-' + dayStr; 14389 // append a day header 14390 innerNodes.push(createElement(ListViewHeaderRow, { key: dayStr, cellId: dateHeaderId, dayDate: dayDates[dayIndex], todayRange: todayRange })); 14391 daySegs = sortEventSegs(daySegs, options.eventOrder); 14392 for (var _i = 0, daySegs_1 = daySegs; _i < daySegs_1.length; _i++) { 14393 var seg = daySegs_1[_i]; 14394 innerNodes.push(createElement(ListViewEventRow, __assign({ key: dayStr + ':' + seg.eventRange.instance.instanceId /* are multiple segs for an instanceId */, seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, timeHeaderId: timeHeaderId, eventHeaderId: eventHeaderId, dateHeaderId: dateHeaderId }, getSegMeta(seg, todayRange, nowDate)))); 14395 } 14396 } 14397 } 14398 return (createElement("table", { className: 'fc-list-table ' + theme.getClass('table') }, 14399 createElement("thead", null, 14400 createElement("tr", null, 14401 createElement("th", { scope: "col", id: timeHeaderId }, options.timeHint), 14402 createElement("th", { scope: "col", "aria-hidden": true }), 14403 createElement("th", { scope: "col", id: eventHeaderId }, options.eventHint))), 14404 createElement("tbody", null, innerNodes))); 14405 })); 14406 }; 14407 ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) { 14408 return this.eventRangesToSegs(sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges); 14409 }; 14410 ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) { 14411 var segs = []; 14412 for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) { 14413 var eventRange = eventRanges_1[_i]; 14414 segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges)); 14415 } 14416 return segs; 14417 }; 14418 ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) { 14419 var dateEnv = this.context.dateEnv; 14420 var nextDayThreshold = this.context.options.nextDayThreshold; 14421 var range = eventRange.range; 14422 var allDay = eventRange.def.allDay; 14423 var dayIndex; 14424 var segRange; 14425 var seg; 14426 var segs = []; 14427 for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) { 14428 segRange = intersectRanges(range, dayRanges[dayIndex]); 14429 if (segRange) { 14430 seg = { 14431 component: this, 14432 eventRange: eventRange, 14433 start: segRange.start, 14434 end: segRange.end, 14435 isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(), 14436 isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(), 14437 dayIndex: dayIndex, 14438 }; 14439 segs.push(seg); 14440 // detect when range won't go fully into the next day, 14441 // and mutate the latest seg to the be the end. 14442 if (!seg.isEnd && !allDay && 14443 dayIndex + 1 < dayRanges.length && 14444 range.end < 14445 dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) { 14446 seg.end = range.end; 14447 seg.isEnd = true; 14448 break; 14449 } 14450 } 14451 } 14452 return segs; 14453 }; 14454 return ListView; 14455 }(DateComponent)); 14456 function renderNoEventsInner(hookProps) { 14457 return hookProps.text; 14458 } 14459 function computeDateVars(dateProfile) { 14460 var dayStart = startOfDay(dateProfile.renderRange.start); 14461 var viewEnd = dateProfile.renderRange.end; 14462 var dayDates = []; 14463 var dayRanges = []; 14464 while (dayStart < viewEnd) { 14465 dayDates.push(dayStart); 14466 dayRanges.push({ 14467 start: dayStart, 14468 end: addDays(dayStart, 1), 14469 }); 14470 dayStart = addDays(dayStart, 1); 14471 } 14472 return { dayDates: dayDates, dayRanges: dayRanges }; 14473 } 14474 // Returns a sparse array of arrays, segs grouped by their dayIndex 14475 function groupSegsByDay(segs) { 14476 var segsByDay = []; // sparse array 14477 var i; 14478 var seg; 14479 for (i = 0; i < segs.length; i += 1) { 14480 seg = segs[i]; 14481 (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = [])) 14482 .push(seg); 14483 } 14484 return segsByDay; 14485 } 14486 14487 var OPTION_REFINERS$1 = { 14488 listDayFormat: createFalsableFormatter, 14489 listDaySideFormat: createFalsableFormatter, 14490 noEventsClassNames: identity, 14491 noEventsContent: identity, 14492 noEventsDidMount: identity, 14493 noEventsWillUnmount: identity, 14494 // noEventsText is defined in base options 14495 }; 14496 function createFalsableFormatter(input) { 14497 return input === false ? null : createFormatter(input); 14498 } 14499 14500 var listPlugin = createPlugin({ 14501 optionRefiners: OPTION_REFINERS$1, 14502 views: { 14503 list: { 14504 component: ListView, 14505 buttonTextKey: 'list', 14506 listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' }, // like "January 1, 2016" 14507 }, 14508 listDay: { 14509 type: 'list', 14510 duration: { days: 1 }, 14511 listDayFormat: { weekday: 'long' }, // day-of-week is all we need. full date is probably in headerToolbar 14512 }, 14513 listWeek: { 14514 type: 'list', 14515 duration: { weeks: 1 }, 14516 listDayFormat: { weekday: 'long' }, 14517 listDaySideFormat: { month: 'long', day: 'numeric', year: 'numeric' }, 14518 }, 14519 listMonth: { 14520 type: 'list', 14521 duration: { month: 1 }, 14522 listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have 14523 }, 14524 listYear: { 14525 type: 'list', 14526 duration: { year: 1 }, 14527 listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have 14528 }, 14529 }, 14530 });
14531 14532 var BootstrapTheme$1 = /** @class */ (function (_super) { 14533 __extends(BootstrapTheme, _super); 14534 function BootstrapTheme() { 14535 return _super !== null && _super.apply(this, arguments) || this; 14536 } 14537 return BootstrapTheme; 14538 }(Theme)); 14539 BootstrapTheme$1.prototype.classes = { 14540 root: 'fc-theme-bootstrap', 14541 table: 'table-bordered', 14542 tableCellShaded: 'table-active', 14543 buttonGroup: 'btn-group', 14544 button: 'btn btn-primary', 14545 buttonActive: 'active', 14546 popover: 'popover', 14547 popoverHeader: 'popover-header', 14548 popoverContent: 'popover-body', 14549 }; 14550 BootstrapTheme$1.prototype.baseIconClass = 'fa'; 14551 BootstrapTheme$1.prototype.iconClasses = { 14552 close: 'fa-times', 14553 prev: 'fa-chevron-left', 14554 next: 'fa-chevron-right', 14555 prevYear: 'fa-angle-double-left', 14556 nextYear: 'fa-angle-double-right', 14557 }; 14558 BootstrapTheme$1.prototype.rtlIconClasses = { 14559 prev: 'fa-chevron-right', 14560 next: 'fa-chevron-left', 14561 prevYear: 'fa-angle-double-right', 14562 nextYear: 'fa-angle-double-left', 14563 }; 14564 BootstrapTheme$1.prototype.iconOverrideOption = 'bootstrapFontAwesome'; // TODO: make TS-friendly. move the option-processing into this plugin 14565 BootstrapTheme$1.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome'; 14566 BootstrapTheme$1.prototype.iconOverridePrefix = 'fa-'; 14567 var plugin$1 = createPlugin({ 14568 themeClasses: { 14569 bootstrap: BootstrapTheme$1, 14570 }, 14571 }); 14572 14573 var BootstrapTheme = /** @class */ (function (_super) { 14574 __extends(BootstrapTheme, _super); 14575 function BootstrapTheme() { 14576 return _super !== null && _super.apply(this, arguments) || this; 14577 } 14578 return BootstrapTheme; 14579 }(Theme)); 14580 BootstrapTheme.prototype.classes = { 14581 root: 'fc-theme-bootstrap5', 14582 tableCellShaded: 'fc-theme-bootstrap5-shaded', 14583 buttonGroup: 'btn-group', 14584 button: 'btn btn-primary', 14585 buttonActive: 'active', 14586 popover: 'popover', 14587 popoverHeader: 'popover-header', 14588 popoverContent: 'popover-body', 14589 }; 14590 BootstrapTheme.prototype.baseIconClass = 'bi'; 14591 BootstrapTheme.prototype.iconClasses = { 14592 close: 'bi-x-lg', 14593 prev: 'bi-chevron-left', 14594 next: 'bi-chevron-right', 14595 prevYear: 'bi-chevron-double-left', 14596 nextYear: 'bi-chevron-double-right', 14597 }; 14598 BootstrapTheme.prototype.rtlIconClasses = { 14599 prev: 'bi-chevron-right', 14600 next: 'bi-chevron-left', 14601 prevYear: 'bi-chevron-double-right', 14602 nextYear: 'bi-chevron-double-left', 14603 }; 14604 // wtf 14605 BootstrapTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly 14606 BootstrapTheme.prototype.iconOverrideCustomButtonOption = 'icon'; 14607 BootstrapTheme.prototype.iconOverridePrefix = 'bi-'; 14608 var plugin = createPlugin({ 14609 themeClasses: { 14610 bootstrap5: BootstrapTheme, 14611 }, 14612 }); 14613 14614 // rename this file to options.ts like other packages? 14615 var OPTION_REFINERS = { 14616 googleCalendarApiKey: String, 14617 }; 14618 14619 var EVENT_SOURCE_REFINERS = { 14620 googleCalendarApiKey: String, 14621 googleCalendarId: String, 14622 googleCalendarApiBase: String, 14623 extraParams: identity, 14624 }; 14625 14626 // TODO: expose somehow 14627 var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars'; 14628 var eventSourceDef = { 14629 parseMeta: function (refined) { 14630 var googleCalendarId = refined.googleCalendarId; 14631 if (!googleCalendarId && refined.url) { 14632 googleCalendarId = parseGoogleCalendarId(refined.url); 14633 } 14634 if (googleCalendarId) { 14635 return { 14636 googleCalendarId: googleCalendarId, 14637 googleCalendarApiKey: refined.googleCalendarApiKey, 14638 googleCalendarApiBase: refined.googleCalendarApiBase, 14639 extraParams: refined.extraParams, 14640 }; 14641 } 14642 return null; 14643 },
14644 fetch: function (arg, onSuccess, onFailure) { 14645 var _a = arg.context, dateEnv = _a.dateEnv, options = _a.options; 14646 var meta = arg.eventSource.meta; 14647 var apiKey = meta.googleCalendarApiKey || options.googleCalendarApiKey; 14648 if (!apiKey) { 14649 onFailure({ 14650 message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/', 14651 }); 14652 } 14653 else { 14654 var url = buildUrl(meta); 14655 // TODO: make DRY with json-feed-event-source 14656 var extraParams = meta.extraParams; 14657 var extraParamsObj = typeof extraParams === 'function' ? extraParams() : extraParams; 14658 var requestParams_1 = buildRequestParams(arg.range, apiKey, extraParamsObj, dateEnv); 14659 requestJson('GET', url, requestParams_1, function (body, xhr) { 14660 if (body.error) { 14661 onFailure({ 14662 message: 'Google Calendar API: ' + body.error.message, 14663 errors: body.error.errors, 14664 xhr: xhr, 14665 }); 14666 } 14667 else { 14668 onSuccess({ 14669 rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone), 14670 xhr: xhr, 14671 }); 14672 } 14673 }, function (message, xhr) { 14674 onFailure({ message: message, xhr: xhr }); 14675 }); 14676 } 14677 }, 14678 }; 14679 function parseGoogleCalendarId(url) { 14680 var match; 14681 // detect if the ID was specified as a single string. 14682 // will match calendars like "[email protected]" in addition to person email calendars. 14683 if (/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) { 14684 return url; 14685 } 14686 if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec(url)) || 14687 (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(url))) { 14688 return decodeURIComponent(match[1]); 14689 } 14690 return null; 14691 } 14692 function buildUrl(meta) { 14693 var apiBase = meta.googleCalendarApiBase; 14694 if (!apiBase) { 14695 apiBase = API_BASE; 14696 } 14697 return apiBase + '/' + encodeURIComponent(meta.googleCalendarId) + '/events'; 14698 } 14699 function buildRequestParams(range, apiKey, extraParams, dateEnv) { 14700 var params; 14701 var startStr; 14702 var endStr; 14703 if (dateEnv.canComputeOffset) { 14704 // strings will naturally have offsets, which GCal needs 14705 startStr = dateEnv.formatIso(range.start); 14706 endStr = dateEnv.formatIso(range.end); 14707 } 14708 else { 14709 // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day 14710 // from the UTC day-start to guarantee we're getting all the events 14711 // (start/end will be UTC-coerced dates, so toISOString is okay) 14712 startStr = addDays(range.start, -1).toISOString(); 14713 endStr = addDays(range.end, 1).toISOString(); 14714 } 14715 params = __assign(__assign({}, (extraParams || {})), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 }); 14716 if (dateEnv.timeZone !== 'local') { 14717 params.timeZone = dateEnv.timeZone; 14718 } 14719 return params; 14720 } 14721 function gcalItemsToRawEventDefs(items, gcalTimezone) { 14722 return items.map(function (item) { return gcalItemToRawEventDef(item, gcalTimezone); }); 14723 } 14724 function gcalItemToRawEventDef(item, gcalTimezone) { 14725 var url = item.htmlLink || null; 14726 // make the URLs for each event show times in the correct timezone 14727 if (url && gcalTimezone) { 14728 url = injectQsComponent(url, 'ctz=' + gcalTimezone); 14729 } 14730 return { 14731 id: item.id, 14732 title: item.summary, 14733 start: item.start.dateTime || item.start.date, 14734 end: item.end.dateTime || item.end.date, 14735 url: url, 14736 location: item.location, 14737 description: item.description, 14738 attachments: item.attachments || [], 14739 extendedProps: (item.extendedProperties || {}).shared || {}, 14740 }; 14741 } 14742 // Injects a string like "arg=value" into the querystring of a URL 14743 // TODO: move to a general util file? 14744 function injectQsComponent(url, component) { 14745 // inject it after the querystring but before the fragment 14746 return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) { return (qs ? qs + '&' : '?') + component + hash; }); 14747 } 14748 var googleCalendarPlugin = createPlugin({ 14749 eventSourceDefs: [eventSourceDef], 14750 optionRefiners: OPTION_REFINERS, 14751 eventSourceRefiners: EVENT_SOURCE_REFINERS, 14752 });
14753 14754 globalPlugins.push(interactionPlugin, dayGridPlugin, timeGridPlugin, listPlugin, plugin$1, plugin, googleCalendarPlugin); 14755 14756 exports.BASE_OPTION_DEFAULTS = BASE_OPTION_DEFAULTS; 14757 exports.BASE_OPTION_REFINERS = BASE_OPTION_REFINERS; 14758 exports.BaseComponent = BaseComponent; 14759 exports.BgEvent = BgEvent; 14760 exports.BootstrapTheme = BootstrapTheme$1; 14761 exports.Calendar = Calendar; 14762 exports.CalendarApi = CalendarApi; 14763 exports.CalendarContent = CalendarContent; 14764 exports.CalendarDataManager = CalendarDataManager; 14765 exports.CalendarDataProvider = CalendarDataProvider; 14766 exports.CalendarRoot = CalendarRoot; 14767 exports.Component = Component; 14768 exports.ContentHook = ContentHook; 14769 exports.CustomContentRenderContext = CustomContentRenderContext; 14770 exports.DateComponent = DateComponent; 14771 exports.DateEnv = DateEnv; 14772 exports.DateProfileGenerator = DateProfileGenerator; 14773 exports.DayCellContent = DayCellContent; 14774 exports.DayCellRoot = DayCellRoot; 14775 exports.DayGridView = DayTableView; 14776 exports.DayHeader = DayHeader;
14777 exports.DaySeriesModel = DaySeriesModel; 14778 exports.DayTable = DayTable; 14779 exports.DayTableModel = DayTableModel; 14780 exports.DayTableSlicer = DayTableSlicer; 14781 exports.DayTimeCols = DayTimeCols; 14782 exports.DayTimeColsSlicer = DayTimeColsSlicer; 14783 exports.DayTimeColsView = DayTimeColsView; 14784 exports.DelayedRunner = DelayedRunner; 14785 exports.Draggable = ExternalDraggable; 14786 exports.ElementDragging = ElementDragging; 14787 exports.ElementScrollController = ElementScrollController; 14788 exports.Emitter = Emitter; 14789 exports.EventApi = EventApi; 14790 exports.EventRoot = EventRoot; 14791 exports.EventSourceApi = EventSourceApi; 14792 exports.FeaturefulElementDragging = FeaturefulElementDragging; 14793 exports.Fragment = Fragment; 14794 exports.Interaction = Interaction; 14795 exports.ListView = ListView; 14796 exports.MoreLinkRoot = MoreLinkRoot; 14797 exports.MountHook = MountHook; 14798 exports.NamedTimeZoneImpl = NamedTimeZoneImpl; 14799 exports.NowIndicatorRoot = NowIndicatorRoot; 14800 exports.NowTimer = NowTimer; 14801 exports.PointerDragging = PointerDragging; 14802 exports.PositionCache = PositionCache; 14803 exports.RefMap = RefMap; 14804 exports.RenderHook = RenderHook; 14805 exports.ScrollController = ScrollController; 14806 exports.ScrollResponder = ScrollResponder; 14807 exports.Scroller = Scroller; 14808 exports.SegHierarchy = SegHierarchy; 14809 exports.SimpleScrollGrid = SimpleScrollGrid; 14810 exports.Slicer = Slicer; 14811 exports.Splitter = Splitter; 14812 exports.StandardEvent = StandardEvent; 14813 exports.Table = Table; 14814 exports.TableDateCell = TableDateCell; 14815 exports.TableDowCell = TableDowCell; 14816 exports.TableView = TableView; 14817 exports.Theme = Theme; 14818 exports.ThirdPartyDraggable = ThirdPartyDraggable; 14819 exports.TimeCols = TimeCols; 14820 exports.TimeColsSlatsCoords = TimeColsSlatsCoords; 14821 exports.TimeColsView = TimeColsView; 14822 exports.ViewApi = ViewApi; 14823 exports.ViewContextType = ViewContextType; 14824 exports.ViewRoot = ViewRoot; 14825 exports.WeekNumberRoot = WeekNumberRoot; 14826 exports.WindowScrollController = WindowScrollController; 14827 exports.addDays = addDays; 14828 exports.addDurations = addDurations; 14829 exports.addMs = addMs; 14830 exports.addWeeks = addWeeks; 14831 exports.allowContextMenu = allowContextMenu; 14832 exports.allowSelection = allowSelection; 14833 exports.applyMutationToEventStore = applyMutationToEventStore; 14834 exports.applyStyle = applyStyle; 14835 exports.applyStyleProp = applyStyleProp; 14836 exports.asCleanDays = asCleanDays; 14837 exports.asRoughMinutes = asRoughMinutes; 14838 exports.asRoughMs = asRoughMs; 14839 exports.asRoughSeconds = asRoughSeconds; 14840 exports.binarySearch = binarySearch; 14841 exports.buildClassNameNormalizer = buildClassNameNormalizer; 14842 exports.buildDayRanges = buildDayRanges; 14843 exports.buildDayTableModel = buildDayTableModel; 14844 exports.buildEntryKey = buildEntryKey; 14845 exports.buildEventApis = buildEventApis; 14846 exports.buildEventRangeKey = buildEventRangeKey; 14847 exports.buildHashFromArray = buildHashFromArray; 14848 exports.buildIsoString = buildIsoString; 14849 exports.buildNavLinkAttrs = buildNavLinkAttrs; 14850 exports.buildSegCompareObj = buildSegCompareObj; 14851 exports.buildSegTimeText = buildSegTimeText; 14852 exports.buildSlatMetas = buildSlatMetas; 14853 exports.buildTimeColsModel = buildTimeColsModel; 14854 exports.collectFromHash = collectFromHash; 14855 exports.combineEventUis = combineEventUis; 14856 exports.compareByFieldSpec = compareByFieldSpec; 14857 exports.compareByFieldSpecs = compareByFieldSpecs; 14858 exports.compareNumbers = compareNumbers; 14859 exports.compareObjs = compareObjs; 14860 exports.computeEarliestSegStart = computeEarliestSegStart; 14861 exports.computeEdges = computeEdges; 14862 exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat; 14863 exports.computeHeightAndMargins = computeHeightAndMargins; 14864 exports.computeInnerRect = computeInnerRect; 14865 exports.computeRect = computeRect; 14866 exports.computeSegDraggable = computeSegDraggable; 14867 exports.computeSegEndResizable = computeSegEndResizable; 14868 exports.computeSegStartResizable = computeSegStartResizable; 14869 exports.computeShrinkWidth = computeShrinkWidth; 14870 exports.computeSmallestCellWidth = computeSmallestCellWidth; 14871 exports.computeVisibleDayRange = computeVisibleDayRange; 14872 exports.config = config; 14873 exports.constrainPoint = constrainPoint; 14874 exports.createAriaClickAttrs = createAriaClickAttrs; 14875 exports.createContext = createContext; 14876 exports.createDuration = createDuration; 14877 exports.createElement = createElement; 14878 exports.createEmptyEventStore = createEmptyEventStore; 14879 exports.createEventInstance = createEventInstance; 14880 exports.createEventUi = createEventUi; 14881 exports.createFormatter = createFormatter; 14882 exports.createPlugin = createPlugin; 14883 exports.createPortal = createPortal; 14884 exports.createRef = createRef; 14885 exports.diffDates = diffDates; 14886 exports.diffDayAndTime = diffDayAndTime; 14887 exports.diffDays = diffDays; 14888 exports.diffPoints = diffPoints; 14889 exports.diffWeeks = diffWeeks; 14890 exports.diffWholeDays = diffWholeDays; 14891 exports.diffWholeWeeks = diffWholeWeeks; 14892 exports.disableCursor = disableCursor; 14893 exports.elementClosest = elementClosest; 14894 exports.elementMatches = elementMatches; 14895 exports.enableCursor = enableCursor; 14896 exports.eventTupleToStore = eventTupleToStore; 14897 exports.filterEventStoreDefs = filterEventStoreDefs; 14898 exports.filterHash = filterHash; 14899 exports.findDirectChildren = findDirectChildren; 14900 exports.findElements = findElements; 14901 exports.flexibleCompare = flexibleCompare; 14902 exports.flushSync = flushSync; 14903 exports.formatDate = formatDate; 14904 exports.formatDayString = formatDayString; 14905 exports.formatIsoTimeString = formatIsoTimeString; 14906 exports.formatRange = formatRange; 14907 exports.getAllowYScrolling = getAllowYScrolling; 14908 exports.getCanVGrowWithinCell = getCanVGrowWithinCell; 14909 exports.getClippingParents = getClippingParents; 14910 exports.getDateMeta = getDateMeta; 14911 exports.getDayClassNames = getDayClassNames; 14912 exports.getDefaultEventEnd = getDefaultEventEnd; 14913 exports.getElRoot = getElRoot; 14914 exports.getElSeg = getElSeg; 14915 exports.getEntrySpanEnd = getEntrySpanEnd; 14916 exports.getEventClassNames = getEventClassNames; 14917 exports.getEventTargetViaRoot = getEventTargetViaRoot; 14918 exports.getIsRtlScrollbarOnLeft = getIsRtlScrollbarOnLeft; 14919 exports.getRectCenter = getRectCenter; 14920 exports.getRelevantEvents = getRelevantEvents; 14921 exports.getScrollGridClassNames = getScrollGridClassNames;
14922 exports.getScrollbarWidths = getScrollbarWidths; 14923 exports.getSectionClassNames = getSectionClassNames; 14924 exports.getSectionHasLiquidHeight = getSectionHasLiquidHeight; 14925 exports.getSegAnchorAttrs = getSegAnchorAttrs; 14926 exports.getSegMeta = getSegMeta; 14927 exports.getSlotClassNames = getSlotClassNames; 14928 exports.getStickyFooterScrollbar = getStickyFooterScrollbar; 14929 exports.getStickyHeaderDates = getStickyHeaderDates; 14930 exports.getUnequalProps = getUnequalProps; 14931 exports.getUniqueDomId = getUniqueDomId; 14932 exports.globalLocales = globalLocales; 14933 exports.globalPlugins = globalPlugins; 14934 exports.greatestDurationDenominator = greatestDurationDenominator; 14935 exports.groupIntersectingEntries = groupIntersectingEntries; 14936 exports.guid = guid; 14937 exports.hasBgRendering = hasBgRendering; 14938 exports.hasShrinkWidth = hasShrinkWidth; 14939 exports.identity = identity; 14940 exports.interactionSettingsStore = interactionSettingsStore; 14941 exports.interactionSettingsToStore = interactionSettingsToStore; 14942 exports.intersectRanges = intersectRanges; 14943 exports.intersectRects = intersectRects; 14944 exports.intersectSpans = intersectSpans; 14945 exports.isArraysEqual = isArraysEqual; 14946 exports.isColPropsEqual = isColPropsEqual; 14947 exports.isDateSelectionValid = isDateSelectionValid; 14948 exports.isDateSpansEqual = isDateSpansEqual; 14949 exports.isInt = isInt; 14950 exports.isInteractionValid = isInteractionValid; 14951 exports.isMultiDayRange = isMultiDayRange; 14952 exports.isPropsEqual = isPropsEqual; 14953 exports.isPropsValid = isPropsValid; 14954 exports.isValidDate = isValidDate; 14955 exports.joinSpans = joinSpans; 14956 exports.listenBySelector = listenBySelector; 14957 exports.mapHash = mapHash; 14958 exports.memoize = memoize; 14959 exports.memoizeArraylike = memoizeArraylike; 14960 exports.memoizeHashlike = memoizeHashlike; 14961 exports.memoizeObjArg = memoizeObjArg; 14962 exports.mergeEventStores = mergeEventStores; 14963 exports.multiplyDuration = multiplyDuration; 14964 exports.padStart = padStart; 14965 exports.parseBusinessHours = parseBusinessHours; 14966 exports.parseClassNames = parseClassNames; 14967 exports.parseDragMeta = parseDragMeta; 14968 exports.parseEventDef = parseEventDef; 14969 exports.parseFieldSpecs = parseFieldSpecs; 14970 exports.parseMarker = parse; 14971 exports.pointInsideRect = pointInsideRect; 14972 exports.preventContextMenu = preventContextMenu; 14973 exports.preventDefault = preventDefault; 14974 exports.preventSelection = preventSelection; 14975 exports.rangeContainsMarker = rangeContainsMarker; 14976 exports.rangeContainsRange = rangeContainsRange; 14977 exports.rangesEqual = rangesEqual; 14978 exports.rangesIntersect = rangesIntersect; 14979 exports.refineEventDef = refineEventDef; 14980 exports.refineProps = refineProps; 14981 exports.removeElement = removeElement; 14982 exports.removeExact = removeExact; 14983 exports.render = render; 14984 exports.renderChunkContent = renderChunkContent; 14985 exports.renderFill = renderFill; 14986 exports.renderMicroColGroup = renderMicroColGroup; 14987 exports.renderScrollShim = renderScrollShim; 14988 exports.requestJson = requestJson; 14989 exports.sanitizeShrinkWidth = sanitizeShrinkWidth; 14990 exports.setElSeg = setElSeg; 14991 exports.setRef = setRef; 14992 exports.sliceEventStore = sliceEventStore; 14993 exports.sliceEvents = sliceEvents; 14994 exports.sortEventSegs = sortEventSegs; 14995 exports.startOfDay = startOfDay; 14996 exports.translateRect = translateRect; 14997 exports.triggerDateSelect = triggerDateSelect; 14998 exports.unmountComponentAtNode = unmountComponentAtNode; 14999 exports.unpromisify = unpromisify; 15000 exports.version = version; 15001 exports.whenTransitionDone = whenTransitionDone; 15002 exports.wholeDivideDurations = wholeDivideDurations; 15003
15004 Object.defineProperty(exports, '__esModule', { value: true }); 15005 15006 return exports; 15007 15008}({}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.