vendor: 4,521 bytes, lines 1-61
1/*! 2FullCalendar v5.11.3 3Docs & License: https://fullcalendar.io/ 4(c) 2022 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) {
vendor: 16,153 bytes, lines 294-732
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'];
vendor: 8,484 bytes, lines 897-1140
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(workerFunc, resEquality, teardownFunc) { 1211 var _this = this; 1212 var currentArgHash = {}; 1213 var currentResHash = {}; 1214 return function (newArgHash) { 1215 var newResHash = {}; 1216 for (var key in newArgHash) { 1217 if (!currentResHash[key]) { 1218 newResHash[key] = workerFunc.apply(_this, newArgHash[key]); 1219 } 1220 else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) { 1221 if (teardownFunc) { 1222 teardownFunc(currentResHash[key]); 1223 } 1224 var res = workerFunc.apply(_this, newArgHash[key]); 1225 newResHash[key] = (resEquality && resEquality(res, currentResHash[key])) 1226 ? currentResHash[key] 1227 : res; 1228 } 1229 else { 1230 newResHash[key] = currentResHash[key]; 1231 } 1232 } 1233 currentArgHash = newArgHash; 1234 currentResHash = newResHash; 1235 return newResHash; 1236 }; 1237 } 1238 1239 var EXTENDED_SETTINGS_AND_SEVERITIES = { 1240 week: 3, 1241 separator: 0, 1242 omitZeroMinute: 0, 1243 meridiem: 0, 1244 omitCommas: 0, 1245 }; 1246 var STANDARD_DATE_PROP_SEVERITIES = { 1247 timeZoneName: 7, 1248 era: 6, 1249 year: 5, 1250 month: 4, 1251 day: 2, 1252 weekday: 2, 1253 hour: 1, 1254 minute: 1, 1255 second: 1, 1256 }; 1257 var MERIDIEM_RE = /\s*([ap])\.?m\.?/i;
1257 // eats up leading spaces too 1258 var COMMA_RE = /,/g; // we need re for globalness 1259 var MULTI_SPACE_RE = /\s+/g; 1260 var LTR_RE = /\u200e/g; // control character 1261 var UTC_RE = /UTC|GMT/; 1262 var NativeFormatter = /** @class */ (function () { 1263 function NativeFormatter(formatSettings) { 1264 var standardDateProps = {}; 1265 var extendedSettings = {}; 1266 var severity = 0; 1267 for (var name_1 in formatSettings) { 1268 if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) { 1269 extendedSettings[name_1] = formatSettings[name_1]; 1270 severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity); 1271 } 1272 else { 1273 standardDateProps[name_1] = formatSettings[name_1]; 1274 if (name_1 in STANDARD_DATE_PROP_SEVERITIES) { // TODO: what about hour12? no severity 1275 severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity); 1276 } 1277 } 1278 } 1279 this.standardDateProps = standardDateProps; 1280 this.extendedSettings = extendedSettings; 1281 this.severity = severity; 1282 this.buildFormattingFunc = memoize(buildFormattingFunc); 1283 } 1284 NativeFormatter.prototype.format = function (date, context) { 1285 return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date); 1286 }; 1287 NativeFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) { 1288 var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings; 1289 var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem); 1290 if (!diffSeverity) { 1291 return this.format(start, context); 1292 } 1293 var biggestUnitForPartial = diffSeverity; 1294 if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time 1295 (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') && 1296 (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') && 1297 (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) { 1298 biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time 1299 } 1300 var full0 = this.format(start, context); 1301 var full1 = this.format(end, context); 1302 if (full0 === full1) { 1303 return full0; 1304 } 1305 var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial); 1306 var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context); 1307 var partial0 = partialFormattingFunc(start); 1308 var partial1 = partialFormattingFunc(end); 1309 var insertion = findCommonInsertion(full0, partial0, full1, partial1); 1310 var separator = extendedSettings.separator || betterDefaultSeparator || context.defaultSeparator || ''; 1311 if (insertion) { 1312 return insertion.before + partial0 + separator + partial1 + insertion.after; 1313 } 1314 return full0 + separator + full1; 1315 }; 1316 NativeFormatter.prototype.getLargestUnit = function () { 1317 switch (this.severity) { 1318 case 7: 1319 case 6: 1320 case 5: 1321 return 'year'; 1322 case 4: 1323 return 'month'; 1324 case 3: 1325 return 'week'; 1326 case 2: 1327 return 'day'; 1328 default: 1329 return 'time'; // really? 1330 } 1331 }; 1332 return NativeFormatter; 1333 }()); 1334 function buildFormattingFunc(standardDateProps, extendedSettings, context) { 1335 var standardDatePropCnt = Object.keys(standardDateProps).length; 1336 if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') { 1337 return function (date) { return (formatTimeZoneOffset(date.timeZoneOffset)); }; 1338 } 1339 if (standardDatePropCnt === 0 && extendedSettings.week) { 1340 return function (date) { return (formatWeekNumber(context.computeWeekNumber(date.marker), context.weekText, context.weekTextLong, context.locale, extendedSettings.week)); }; 1341 } 1342 return buildNativeFormattingFunc(standardDateProps, extendedSettings, context); 1343 } 1344 function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) { 1345 standardDateProps = __assign({}, standardDateProps); // copy 1346 extendedSettings = __assign({}, extendedSettings); // copy 1347 sanitizeSettings(standardDateProps, extendedSettings); 1348 standardDateProps.timeZone = 'UTC';
1348 // we leverage the only guaranteed timeZone for our UTC markers 1349 var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps); 1350 var zeroFormat; // needed? 1351 if (extendedSettings.omitZeroMinute) { 1352 var zeroProps = __assign({}, standardDateProps); 1353 delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings 1354 zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps); 1355 } 1356 return function (date) { 1357 var marker = date.marker; 1358 var format; 1359 if (zeroFormat && !marker.getUTCMinutes()) { 1360 format = zeroFormat; 1361 } 1362 else { 1363 format = normalFormat; 1364 } 1365 var s = format.format(marker); 1366 return postProcess(s, date, standardDateProps, extendedSettings, context); 1367 }; 1368 } 1369 function sanitizeSettings(standardDateProps, extendedSettings) { 1370 // deal with a browser inconsistency where formatting the timezone 1371 // requires that the hour/minute be present. 1372 if (standardDateProps.timeZoneName) { 1373 if (!standardDateProps.hour) { 1374 standardDateProps.hour = '2-digit'; 1375 } 1376 if (!standardDateProps.minute) { 1377 standardDateProps.minute = '2-digit'; 1378 } 1379 } 1380 // only support short timezone names 1381 if (standardDateProps.timeZoneName === 'long') { 1382 standardDateProps.timeZoneName = 'short'; 1383 } 1384 // if requesting to display seconds, MUST display minutes 1385 if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) { 1386 delete extendedSettings.omitZeroMinute; 1387 } 1388 } 1389 function postProcess(s, date, standardDateProps, extendedSettings, context) { 1390 s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes 1391 if (standardDateProps.timeZoneName === 'short') { 1392 s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ? 1393 'UTC' : // important to normalize for IE, which does "GMT" 1394 formatTimeZoneOffset(date.timeZoneOffset)); 1395 } 1396 if (extendedSettings.omitCommas) { 1397 s = s.replace(COMMA_RE, '').trim(); 1398 } 1399 if (extendedSettings.omitZeroMinute) { 1400 s = s.replace(':00', ''); // zeroFormat doesn't always achieve this 1401 } 1402 // ^ do anything that might create adjacent spaces before this point, 1403 // because MERIDIEM_RE likes to eat up loading spaces 1404 if (extendedSettings.meridiem === false) { 1405 s = s.replace(MERIDIEM_RE, '').trim(); 1406 } 1407 else if (extendedSettings.meridiem === 'narrow') { // a/p 1408 s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase(); }); 1409 } 1410 else if (extendedSettings.meridiem === 'short') { // am/pm 1411 s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase() + "m"; }); 1412 } 1413 else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase 1414 s = s.replace(MERIDIEM_RE, function (m0) { return m0.toLocaleLowerCase(); }); 1415 } 1416 s = s.replace(MULTI_SPACE_RE, ' '); 1417 s = s.trim(); 1418 return s; 1419 } 1420 function injectTzoStr(s, tzoStr) { 1421 var replaced = false; 1422 s = s.replace(UTC_RE, function () { 1423 replaced = true; 1424 return tzoStr; 1425 }); 1426 // IE11 doesn't include UTC/GMT in the original string, so append to end 1427 if (!replaced) { 1428 s += " " + tzoStr; 1429 } 1430 return s; 1431 } 1432 function formatWeekNumber(num, weekText, weekTextLong, locale, display) { 1433 var parts = []; 1434 if (display === 'long') { 1435 parts.push(weekTextLong); 1436 } 1437 else if (display === 'short' || display === 'narrow') { 1438 parts.push(weekText); 1439 } 1440 if (display === 'long' || display === 'short') { 1441 parts.push(' '); 1442 } 1443 parts.push(locale.simpleNumberFormat.format(num)); 1444 if (locale.options.direction === 'rtl') { // TODO: use control characters instead? 1445 parts.reverse(); 1446 } 1447 return parts.join(''); 1448 } 1449 // Range Formatting Utils 1450 // 0 = exactly the same 1451 // 1 = different by time 1452 // and bigger 1453 function computeMarkerDiffSeverity(d0, d1, ca) { 1454 if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) { 1455 return 5; 1456 } 1457 if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) { 1458 return 4; 1459 } 1460 if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) { 1461 return 2; 1462 } 1463 if (timeAsMs(d0) !== timeAsMs(d1)) { 1464 return 1; 1465 } 1466 return 0; 1467 } 1468 function computePartialFormattingOptions(options, biggestUnit) { 1469 var partialOptions = {}; 1470 for (var name_2 in options) { 1471 if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone) 1472 STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) { 1473 partialOptions[name_2] = options[name_2]; 1474 } 1475 } 1476 return partialOptions; 1477 } 1478 function findCommonInsertion(full0, partial0, full1, partial1) { 1479 var i0 = 0; 1480 while (i0 < full0.length) { 1481 var found0 = full0.indexOf(partial0, i0); 1482 if (found0 === -1) { 1483 break; 1484 } 1485 var before0 = full0.substr(0, found0); 1486 i0 = found0 + partial0.length; 1487 var after0 = full0.substr(i0); 1488 var i1 = 0; 1489 while (i1 < full1.length) { 1490 var found1 = full1.indexOf(partial1, i1);
1491 if (found1 === -1) { 1492 break; 1493 } 1494 var before1 = full1.substr(0, found1); 1495 i1 = found1 + partial1.length; 1496 var after1 = full1.substr(i1); 1497 if (before0 === before1 && after0 === after1) { 1498 return { 1499 before: before0, 1500 after: after0, 1501 }; 1502 } 1503 } 1504 } 1505 return null; 1506 } 1507 1508 function expandZonedMarker(dateInfo, calendarSystem) { 1509 var a = calendarSystem.markerToArray(dateInfo.marker); 1510 return { 1511 marker: dateInfo.marker, 1512 timeZoneOffset: dateInfo.timeZoneOffset, 1513 array: a, 1514 year: a[0], 1515 month: a[1], 1516 day: a[2], 1517 hour: a[3], 1518 minute: a[4], 1519 second: a[5], 1520 millisecond: a[6], 1521 }; 1522 } 1523 1524 function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) { 1525 var startInfo = expandZonedMarker(start, context.calendarSystem); 1526 var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null; 1527 return { 1528 date: startInfo, 1529 start: startInfo, 1530 end: endInfo, 1531 timeZone: context.timeZone, 1532 localeCodes: context.locale.codes, 1533 defaultSeparator: betterDefaultSeparator || context.defaultSeparator, 1534 }; 1535 } 1536 1537 /* 1538 TODO: fix the terminology of "formatter" vs "formatting func" 1539 */ 1540 /* 1541 At the time of instantiation, this object does not know which cmd-formatting system it will use. 1542 It receives this at the time of formatting, as a setting. 1543 */ 1544 var CmdFormatter = /** @class */ (function () { 1545 function CmdFormatter(cmdStr) { 1546 this.cmdStr = cmdStr; 1547 } 1548 CmdFormatter.prototype.format = function (date, context, betterDefaultSeparator) { 1549 return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator)); 1550 }; 1551 CmdFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) { 1552 return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator)); 1553 }; 1554 return CmdFormatter; 1555 }()); 1556 1557 var FuncFormatter = /** @class */ (function () { 1558 function FuncFormatter(func) { 1559 this.func = func; 1560 } 1561 FuncFormatter.prototype.format = function (date, context, betterDefaultSeparator) { 1562 return this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator)); 1563 }; 1564 FuncFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) { 1565 return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator)); 1566 }; 1567 return FuncFormatter; 1568 }()); 1569 1570 function createFormatter(input) { 1571 if (typeof input === 'object' && input) { // non-null object 1572 return new NativeFormatter(input); 1573 } 1574 if (typeof input === 'string') { 1575 return new CmdFormatter(input); 1576 } 1577 if (typeof input === 'function') { 1578 return new FuncFormatter(input); 1579 } 1580 return null; 1581 } 1582 1583 // base options 1584 // ------------ 1585 var BASE_OPTION_REFINERS = { 1586 navLinkDayClick: identity, 1587 navLinkWeekClick: identity, 1588 duration: createDuration, 1589 bootstrapFontAwesome: identity, 1590 buttonIcons: identity, 1591 customButtons: identity, 1592 defaultAllDayEventDuration: createDuration, 1593 defaultTimedEventDuration: createDuration, 1594 nextDayThreshold: createDuration, 1595 scrollTime: createDuration, 1596 scrollTimeReset: Boolean, 1597 slotMinTime: createDuration, 1598 slotMaxTime: createDuration, 1599 dayPopoverFormat: createFormatter, 1600 slotDuration: createDuration, 1601 snapDuration: createDuration, 1602 headerToolbar: identity, 1603 footerToolbar: identity, 1604 defaultRangeSeparator: String, 1605 titleRangeSeparator: String, 1606 forceEventDuration: Boolean, 1607 dayHeaders: Boolean, 1608 dayHeaderFormat: createFormatter, 1609 dayHeaderClassNames: identity, 1610 dayHeaderContent: identity, 1611 dayHeaderDidMount: identity, 1612 dayHeaderWillUnmount: identity, 1613 dayCellClassNames: identity, 1614 dayCellContent: identity, 1615 dayCellDidMount: identity, 1616 dayCellWillUnmount: identity, 1617 initialView: String, 1618 aspectRatio: Number, 1619 weekends: Boolean, 1620 weekNumberCalculation: identity, 1621 weekNumbers: Boolean, 1622 weekNumberClassNames: identity, 1623 weekNumberContent: identity, 1624 weekNumberDidMount: identity, 1625 weekNumberWillUnmount: identity, 1626 editable: Boolean, 1627 viewClassNames: identity, 1628 viewDidMount: identity, 1629 viewWillUnmount: identity, 1630 nowIndicator: Boolean, 1631 nowIndicatorClassNames: identity, 1632 nowIndicatorContent: identity, 1633 nowIndicatorDidMount: identity, 1634 nowIndicatorWillUnmount: identity, 1635 showNonCurrentDates: Boolean, 1636 lazyFetching: Boolean, 1637 startParam: String, 1638 endParam: String, 1639 timeZoneParam: String, 1640 timeZone: String, 1641 locales: identity, 1642 locale: identity, 1643 themeSystem: String, 1644 dragRevertDuration: Number, 1645 dragScroll: Boolean, 1646 allDayMaintainDuration: Boolean, 1647 unselectAuto: Boolean, 1648 dropAccept: identity, 1649 eventOrder: parseFieldSpecs, 1650 eventOrderStrict: Boolean, 1651 handleWindowResize: Boolean, 1652 windowResizeDelay: Number, 1653 longPressDelay: Number, 1654 eventDragMinDistance: Number, 1655 expandRows: Boolean, 1656 height: identity, 1657 contentHeight: identity, 1658 direction: String, 1659 weekNumberFormat: createFormatter, 1660 eventResizableFromStart: Boolean, 1661 displayEventTime: Boolean, 1662 displayEventEnd: Boolean, 1663 weekText: String, 1664 weekTextLong: String, 1665 progressiveEventRendering: Boolean, 1666 businessHours: identity, 1667 initialDate: identity, 1668 now: identity, 1669 eventDataTransform: identity, 1670 stickyHeaderDates: identity, 1671 stickyFooterScrollbar: identity, 1672 viewHeight: identity, 1673 defaultAllDay: Boolean, 1674 eventSourceFailure: identity, 1675 eventSourceSuccess: identity, 1676 eventDisplay: String, 1677 eventStartEditable: Boolean, 1678 eventDurationEditable: Boolean, 1679 eventOverlap: identity, 1680 eventConstraint: identity, 1681 eventAllow: identity,
1682 eventBackgroundColor: String, 1683 eventBorderColor: String, 1684 eventTextColor: String, 1685 eventColor: String, 1686 eventClassNames: identity, 1687 eventContent: identity, 1688 eventDidMount: identity, 1689 eventWillUnmount: identity, 1690 selectConstraint: identity, 1691 selectOverlap: identity, 1692 selectAllow: identity, 1693 droppable: Boolean, 1694 unselectCancel: String, 1695 slotLabelFormat: identity, 1696 slotLaneClassNames: identity, 1697 slotLaneContent: identity, 1698 slotLaneDidMount: identity, 1699 slotLaneWillUnmount: identity, 1700 slotLabelClassNames: identity, 1701 slotLabelContent: identity, 1702 slotLabelDidMount: identity, 1703 slotLabelWillUnmount: identity, 1704 dayMaxEvents: identity, 1705 dayMaxEventRows: identity, 1706 dayMinWidth: Number, 1707 slotLabelInterval: createDuration, 1708 allDayText: String, 1709 allDayClassNames: identity, 1710 allDayContent: identity, 1711 allDayDidMount: identity, 1712 allDayWillUnmount: identity, 1713 slotMinWidth: Number, 1714 navLinks: Boolean, 1715 eventTimeFormat: createFormatter, 1716 rerenderDelay: Number, 1717 moreLinkText: identity, 1718 moreLinkHint: identity, 1719 selectMinDistance: Number, 1720 selectable: Boolean, 1721 selectLongPressDelay: Number, 1722 eventLongPressDelay: Number, 1723 selectMirror: Boolean, 1724 eventMaxStack: Number, 1725 eventMinHeight: Number, 1726 eventMinWidth: Number, 1727 eventShortHeight: Number, 1728 slotEventOverlap: Boolean, 1729 plugins: identity, 1730 firstDay: Number, 1731 dayCount: Number, 1732 dateAlignment: String, 1733 dateIncrement: createDuration, 1734 hiddenDays: identity, 1735 monthMode: Boolean, 1736 fixedWeekCount: Boolean, 1737 validRange: identity, 1738 visibleRange: identity, 1739 titleFormat: identity, 1740 eventInteractive: Boolean, 1741 // only used by list-view, but languages define the value, so we need it in base options 1742 noEventsText: String, 1743 viewHint: identity, 1744 navLinkHint: identity, 1745 closeHint: String, 1746 timeHint: String, 1747 eventHint: String, 1748 moreLinkClick: identity, 1749 moreLinkClassNames: identity, 1750 moreLinkContent: identity, 1751 moreLinkDidMount: identity, 1752 moreLinkWillUnmount: identity, 1753 }; 1754 // do NOT give a type here. need `typeof BASE_OPTION_DEFAULTS` to give real results. 1755 // raw values. 1756 var BASE_OPTION_DEFAULTS = { 1757 eventDisplay: 'auto', 1758 defaultRangeSeparator: ' - ', 1759 titleRangeSeparator: ' \u2013 ', 1760 defaultTimedEventDuration: '01:00:00', 1761 defaultAllDayEventDuration: { day: 1 }, 1762 forceEventDuration: false, 1763 nextDayThreshold: '00:00:00', 1764 dayHeaders: true, 1765 initialView: '', 1766 aspectRatio: 1.35, 1767 headerToolbar: { 1768 start: 'title', 1769 center: '', 1770 end: 'today prev,next', 1771 }, 1772 weekends: true, 1773 weekNumbers: false, 1774 weekNumberCalculation: 'local', 1775 editable: false, 1776 nowIndicator: false, 1777 scrollTime: '06:00:00', 1778 scrollTimeReset: true, 1779 slotMinTime: '00:00:00', 1780 slotMaxTime: '24:00:00', 1781 showNonCurrentDates: true, 1782 lazyFetching: true, 1783 startParam: 'start', 1784 endParam: 'end', 1785 timeZoneParam: 'timeZone', 1786 timeZone: 'local', 1787 locales: [], 1788 locale: '', 1789 themeSystem: 'standard', 1790 dragRevertDuration: 500, 1791 dragScroll: true, 1792 allDayMaintainDuration: false, 1793 unselectAuto: true, 1794 dropAccept: '*', 1795 eventOrder: 'start,-duration,allDay,title', 1796 dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' }, 1797 handleWindowResize: true, 1798 windowResizeDelay: 100, 1799 longPressDelay: 1000, 1800 eventDragMinDistance: 5, 1801 expandRows: false, 1802 navLinks: false, 1803 selectable: false, 1804 eventMinHeight: 15, 1805 eventMinWidth: 30, 1806 eventShortHeight: 30, 1807 }; 1808 // calendar listeners 1809 // ------------------ 1810 var CALENDAR_LISTENER_REFINERS = { 1811 datesSet: identity, 1812 eventsSet: identity, 1813 eventAdd: identity, 1814 eventChange: identity, 1815 eventRemove: identity, 1816 windowResize: identity, 1817 eventClick: identity, 1818 eventMouseEnter: identity, 1819 eventMouseLeave: identity, 1820 select: identity, 1821 unselect: identity, 1822 loading: identity, 1823 // internal 1824 _unmount: identity, 1825 _beforeprint: identity, 1826 _afterprint: identity, 1827 _noEventDrop: identity, 1828 _noEventResize: identity, 1829 _resize: identity, 1830 _scrollRequest: identity, 1831 }; 1832 // calendar-specific options 1833 // ------------------------- 1834 var CALENDAR_OPTION_REFINERS = { 1835 buttonText: identity, 1836 buttonHints: identity, 1837 views: identity, 1838 plugins: identity, 1839 initialEvents: identity,
1840 events: identity, 1841 eventSources: identity, 1842 }; 1843 var COMPLEX_OPTION_COMPARATORS = { 1844 headerToolbar: isMaybeObjectsEqual, 1845 footerToolbar: isMaybeObjectsEqual, 1846 buttonText: isMaybeObjectsEqual, 1847 buttonHints: isMaybeObjectsEqual, 1848 buttonIcons: isMaybeObjectsEqual, 1849 dateIncrement: isMaybeObjectsEqual, 1850 }; 1851 function isMaybeObjectsEqual(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 // HACK for freakin' React StrictMode 5210 PureComponent.prototype.safeSetState = function (newState) { 5211 if (!compareObjs(this.state, __assign(__assign({}, this.state), newState), this.stateEquality)) { 5212 this.setState(newState); 5213 } 5214 }; 5215 PureComponent.addPropsEquality = addPropsEquality; 5216 PureComponent.addStateEquality = addStateEquality; 5217 PureComponent.contextType = ViewContextType; 5218 return PureComponent; 5219 }(Component)); 5220 PureComponent.prototype.propEquality = {}; 5221 PureComponent.prototype.stateEquality = {}; 5222 var BaseComponent = /** @class */ (function (_super) { 5223 __extends(BaseComponent, _super); 5224 function BaseComponent() { 5225 return _super !== null && _super.apply(this, arguments) || this; 5226 } 5227 BaseComponent.contextType = ViewContextType; 5228 return BaseComponent; 5229 }(PureComponent)); 5230 function addPropsEquality(propEquality) { 5231 var hash = Object.create(this.prototype.propEquality); 5232 __assign(hash, propEquality); 5233 this.prototype.propEquality = hash; 5234 } 5235 function addStateEquality(stateEquality) { 5236 var hash = Object.create(this.prototype.stateEquality); 5237 __assign(hash, stateEquality); 5238 this.prototype.stateEquality = hash; 5239 } 5240 // use other one 5241 function setRef(ref, current) { 5242 if (typeof ref === 'function') { 5243 ref(current); 5244 } 5245 else if (ref) { 5246 // see https://github.com/facebook/react/issues/13029 5247 ref.current = current; 5248 } 5249 } 5250 5251 /* 5252 an INTERACTABLE date component 5253 5254 PURPOSES: 5255 - hook up to fg, fill, and mirror renderers 5256 - interface for dragging and hits 5257 */ 5258 var DateComponent = /** @class */ (function (_super) { 5259 __extends(DateComponent, _super); 5260 function DateComponent() { 5261 var _this = _super !== null && _super.apply(this, arguments) || this; 5262 _this.uid = guid(); 5263 return _this; 5264 } 5265 // Hit System 5266 // ----------------------------------------------------------------------------------------------------------------- 5267 DateComponent.prototype.prepareHits = function () { 5268 }; 5269 DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) { 5270 return null; // this should be abstract 5271 }; 5272 // Pointer Interaction Utils 5273 // ----------------------------------------------------------------------------------------------------------------- 5274 DateComponent.prototype.isValidSegDownEl = function (el) { 5275 return !this.props.eventDrag && // HACK 5276 !this.props.eventResize && // HACK 5277 !elementClosest(el, '.fc-event-mirror'); 5278 }; 5279 DateComponent.prototype.isValidDateDownEl = function (el) { 5280 return !elementClosest(el, '.fc-event:not(.fc-bg-event)') && 5281 !elementClosest(el, '.fc-more-link') && // a "more.." link 5282 !elementClosest(el, 'a[data-navlink]') && // a clickable nav link 5283 !elementClosest(el, '.fc-popover'); // hack 5284 }; 5285 return DateComponent; 5286 }(BaseComponent)); 5287 5288 // TODO: easier way to add new hooks? need to update a million things 5289 function createPlugin(input) { 5290 return { 5291 id: guid(), 5292 deps: input.deps || [], 5293 reducers: input.reducers || [], 5294 isLoadingFuncs: input.isLoadingFuncs || [], 5295 contextInit: [].concat(input.contextInit || []), 5296 eventRefiners: input.eventRefiners || {}, 5297 eventDefMemberAdders: input.eventDefMemberAdders || [], 5298 eventSourceRefiners: input.eventSourceRefiners || {}, 5299 isDraggableTransformers: input.isDraggableTransformers || [], 5300 eventDragMutationMassagers: input.eventDragMutationMassagers || [], 5301 eventDefMutationAppliers: input.eventDefMutationAppliers || [], 5302 dateSelectionTransformers: input.dateSelectionTransformers || [], 5303 datePointTransforms: input.datePointTransforms || [], 5304 dateSpanTransforms: input.dateSpanTransforms || [], 5305 views: input.views || {}, 5306 viewPropsTransformers: input.viewPropsTransformers || [], 5307 isPropsValid: input.isPropsValid || null, 5308 externalDefTransforms: input.externalDefTransforms || [], 5309 viewContainerAppends: input.viewContainerAppends || [], 5310 eventDropTransformers: input.eventDropTransformers || [], 5311 componentInteractions: input.componentInteractions || [], 5312 calendarInteractions: input.calendarInteractions || [],
5313 themeClasses: input.themeClasses || {}, 5314 eventSourceDefs: input.eventSourceDefs || [], 5315 cmdFormatter: input.cmdFormatter, 5316 recurringTypes: input.recurringTypes || [], 5317 namedTimeZonedImpl: input.namedTimeZonedImpl, 5318 initialView: input.initialView || '', 5319 elementDraggingImpl: input.elementDraggingImpl, 5320 optionChangeHandlers: input.optionChangeHandlers || {}, 5321 scrollGridImpl: input.scrollGridImpl || null, 5322 contentTypeHandlers: input.contentTypeHandlers || {}, 5323 listenerRefiners: input.listenerRefiners || {}, 5324 optionRefiners: input.optionRefiners || {}, 5325 propSetHandlers: input.propSetHandlers || {}, 5326 }; 5327 } 5328 function buildPluginHooks(pluginDefs, globalDefs) { 5329 var isAdded = {}; 5330 var hooks = { 5331 reducers: [], 5332 isLoadingFuncs: [], 5333 contextInit: [], 5334 eventRefiners: {}, 5335 eventDefMemberAdders: [], 5336 eventSourceRefiners: {}, 5337 isDraggableTransformers: [], 5338 eventDragMutationMassagers: [], 5339 eventDefMutationAppliers: [], 5340 dateSelectionTransformers: [], 5341 datePointTransforms: [], 5342 dateSpanTransforms: [], 5343 views: {}, 5344 viewPropsTransformers: [], 5345 isPropsValid: null, 5346 externalDefTransforms: [], 5347 viewContainerAppends: [], 5348 eventDropTransformers: [], 5349 componentInteractions: [], 5350 calendarInteractions: [], 5351 themeClasses: {}, 5352 eventSourceDefs: [], 5353 cmdFormatter: null, 5354 recurringTypes: [], 5355 namedTimeZonedImpl: null, 5356 initialView: '', 5357 elementDraggingImpl: null, 5358 optionChangeHandlers: {}, 5359 scrollGridImpl: null, 5360 contentTypeHandlers: {}, 5361 listenerRefiners: {}, 5362 optionRefiners: {}, 5363 propSetHandlers: {}, 5364 }; 5365 function addDefs(defs) { 5366 for (var _i = 0, defs_1 = defs; _i < defs_1.length; _i++) { 5367 var def = defs_1[_i]; 5368 if (!isAdded[def.id]) { 5369 isAdded[def.id] = true; 5370 addDefs(def.deps); 5371 hooks = combineHooks(hooks, def); 5372 } 5373 } 5374 } 5375 if (pluginDefs) { 5376 addDefs(pluginDefs); 5377 } 5378 addDefs(globalDefs); 5379 return hooks; 5380 } 5381 function buildBuildPluginHooks() { 5382 var currentOverrideDefs = []; 5383 var currentGlobalDefs = []; 5384 var currentHooks; 5385 return function (overrideDefs, globalDefs) { 5386 if (!currentHooks || !isArraysEqual(overrideDefs, currentOverrideDefs) || !isArraysEqual(globalDefs, currentGlobalDefs)) { 5387 currentHooks = buildPluginHooks(overrideDefs, globalDefs); 5388 } 5389 currentOverrideDefs = overrideDefs; 5390 currentGlobalDefs = globalDefs; 5391 return currentHooks; 5392 }; 5393 } 5394 function combineHooks(hooks0, hooks1) { 5395 return { 5396 reducers: hooks0.reducers.concat(hooks1.reducers), 5397 isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs), 5398 contextInit: hooks0.contextInit.concat(hooks1.contextInit), 5399 eventRefiners: __assign(__assign({}, hooks0.eventRefiners), hooks1.eventRefiners), 5400 eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders), 5401 eventSourceRefiners: __assign(__assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners), 5402 isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers), 5403 eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers), 5404 eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers), 5405 dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers), 5406 datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms), 5407 dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms), 5408 views: __assign(__assign({}, hooks0.views), hooks1.views), 5409 viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers), 5410 isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid, 5411 externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms), 5412 viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends), 5413 eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers), 5414 calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions), 5415 componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
5416 themeClasses: __assign(__assign({}, hooks0.themeClasses), hooks1.themeClasses), 5417 eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs), 5418 cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter, 5419 recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes), 5420 namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl, 5421 initialView: hooks0.initialView || hooks1.initialView, 5422 elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl, 5423 optionChangeHandlers: __assign(__assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers), 5424 scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl, 5425 contentTypeHandlers: __assign(__assign({}, hooks0.contentTypeHandlers), hooks1.contentTypeHandlers), 5426 listenerRefiners: __assign(__assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners), 5427 optionRefiners: __assign(__assign({}, hooks0.optionRefiners), hooks1.optionRefiners), 5428 propSetHandlers: __assign(__assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers), 5429 }; 5430 } 5431 5432 var StandardTheme = /** @class */ (function (_super) { 5433 __extends(StandardTheme, _super); 5434 function StandardTheme() { 5435 return _super !== null && _super.apply(this, arguments) || this; 5436 } 5437 return StandardTheme; 5438 }(Theme)); 5439 StandardTheme.prototype.classes = { 5440 root: 'fc-theme-standard', 5441 tableCellShaded: 'fc-cell-shaded', 5442 buttonGroup: 'fc-button-group', 5443 button: 'fc-button fc-button-primary', 5444 buttonActive: 'fc-button-active', 5445 }; 5446 StandardTheme.prototype.baseIconClass = 'fc-icon'; 5447 StandardTheme.prototype.iconClasses = { 5448 close: 'fc-icon-x', 5449 prev: 'fc-icon-chevron-left', 5450 next: 'fc-icon-chevron-right', 5451 prevYear: 'fc-icon-chevrons-left', 5452 nextYear: 'fc-icon-chevrons-right', 5453 }; 5454 StandardTheme.prototype.rtlIconClasses = { 5455 prev: 'fc-icon-chevron-right', 5456 next: 'fc-icon-chevron-left', 5457 prevYear: 'fc-icon-chevrons-right', 5458 nextYear: 'fc-icon-chevrons-left', 5459 }; 5460 StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly 5461 StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon'; 5462 StandardTheme.prototype.iconOverridePrefix = 'fc-icon-'; 5463 5464 function compileViewDefs(defaultConfigs, overrideConfigs) { 5465 var hash = {}; 5466 var viewType; 5467 for (viewType in defaultConfigs) { 5468 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5469 } 5470 for (viewType in overrideConfigs) { 5471 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5472 } 5473 return hash; 5474 } 5475 function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 5476 if (hash[viewType]) { 5477 return hash[viewType]; 5478 } 5479 var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5480 if (viewDef) { 5481 hash[viewType] = viewDef; 5482 } 5483 return viewDef; 5484 } 5485 function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 5486 var defaultConfig = defaultConfigs[viewType]; 5487 var overrideConfig = overrideConfigs[viewType]; 5488 var queryProp = function (name) { return ((defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] : 5489 ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null)); }; 5490 var theComponent = queryProp('component'); 5491 var superType = queryProp('superType'); 5492 var superDef = null; 5493 if (superType) { 5494 if (superType === viewType) { 5495 throw new Error('Can\'t have a custom view type that references itself'); 5496 } 5497 superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs); 5498 } 5499 if (!theComponent && superDef) { 5500 theComponent = superDef.component; 5501 } 5502 if (!theComponent) { 5503 return null; // don't throw a warning, might be settings for a single-unit view 5504 } 5505 return { 5506 type: viewType, 5507 component: theComponent, 5508 defaults: __assign(__assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})), 5509 overrides: __assign(__assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {})), 5510 }; 5511 } 5512
5513 /* eslint max-classes-per-file: off */ 5514 // NOTE: in JSX, you should always use this class with <HookProps> arg. otherwise, will default to any??? 5515 var RenderHook = /** @class */ (function (_super) { 5516 __extends(RenderHook, _super); 5517 function RenderHook() { 5518 var _this = _super !== null && _super.apply(this, arguments) || this; 5519 _this.rootElRef = createRef(); 5520 _this.handleRootEl = function (el) { 5521 setRef(_this.rootElRef, el); 5522 if (_this.props.elRef) { 5523 setRef(_this.props.elRef, el); 5524 } 5525 }; 5526 return _this; 5527 } 5528 RenderHook.prototype.render = function () { 5529 var _this = this; 5530 var props = this.props; 5531 var hookProps = props.hookProps; 5532 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); })); })); 5533 }; 5534 return RenderHook; 5535 }(BaseComponent)); 5536 // TODO: rename to be about function, not default. use in above type 5537 // for forcing rerender of components that use the ContentHook 5538 var CustomContentRenderContext = createContext(0); 5539 function ContentHook(props) { 5540 return (createElement(CustomContentRenderContext.Consumer, null, function (renderId) { return (createElement(ContentHookInner, __assign({ renderId: renderId }, props))); })); 5541 } 5542 var ContentHookInner = /** @class */ (function (_super) { 5543 __extends(ContentHookInner, _super); 5544 function ContentHookInner() { 5545 var _this = _super !== null && _super.apply(this, arguments) || this; 5546 _this.innerElRef = createRef(); 5547 return _this; 5548 } 5549 ContentHookInner.prototype.render = function () { 5550 return this.props.children(this.innerElRef, this.renderInnerContent()); 5551 }; 5552 ContentHookInner.prototype.componentDidMount = function () { 5553 this.updateCustomContent(); 5554 }; 5555 ContentHookInner.prototype.componentDidUpdate = function () { 5556 this.updateCustomContent(); 5557 }; 5558 ContentHookInner.prototype.componentWillUnmount = function () { 5559 if (this.customContentInfo && this.customContentInfo.destroy) { 5560 this.customContentInfo.destroy(); 5561 } 5562 }; 5563 ContentHookInner.prototype.renderInnerContent = function () { 5564 var customContentInfo = this.customContentInfo; // only populated if using non-[p]react node(s) 5565 var innerContent = this.getInnerContent(); 5566 var meta = this.getContentMeta(innerContent); 5567 // initial run, or content-type changing? (from vue -> react for example) 5568 if (!customContentInfo || customContentInfo.contentKey !== meta.contentKey) { 5569 // clearing old value 5570 if (customContentInfo) { 5571 if (customContentInfo.destroy) { 5572 customContentInfo.destroy(); 5573 } 5574 customContentInfo = this.customContentInfo = null; 5575 } 5576 // assigning new value 5577 if (meta.contentKey) { 5578 customContentInfo = this.customContentInfo = __assign({ contentKey: meta.contentKey, contentVal: innerContent[meta.contentKey] }, meta.buildLifecycleFuncs()); 5579 } 5580 // updating 5581 } 5582 else if (customContentInfo) { 5583 customContentInfo.contentVal = innerContent[meta.contentKey]; 5584 } 5585 return customContentInfo 5586 ? [] // signal that something was specified 5587 : innerContent; // assume a [p]react vdom node. use it 5588 }; 5589 ContentHookInner.prototype.getInnerContent = function () { 5590 var props = this.props; 5591 var innerContent = normalizeContent(props.content, props.hookProps); 5592 if (innerContent === undefined) { // use the default 5593 innerContent = normalizeContent(props.defaultContent, props.hookProps); 5594 } 5595 return innerContent == null ? null : innerContent; // convert undefined to null (better for React) 5596 }; 5597 ContentHookInner.prototype.getContentMeta = function (innerContent) { 5598 var contentTypeHandlers = this.context.pluginHooks.contentTypeHandlers; 5599 var contentKey = ''; 5600 var buildLifecycleFuncs = null; 5601 if (innerContent) { // allowed to be null, for convenience to caller 5602 for (var searchKey in contentTypeHandlers) { 5603 if (innerContent[searchKey] !== undefined) { 5604 contentKey = searchKey; 5605 buildLifecycleFuncs = contentTypeHandlers[searchKey]; 5606 break; 5607 } 5608 } 5609 } 5610 return { contentKey: contentKey, buildLifecycleFuncs: buildLifecycleFuncs }; 5611 }; 5612 ContentHookInner.prototype.updateCustomContent = function () { 5613 if (this.customContentInfo) { // for non-[p]react 5614 this.customContentInfo.render(this.innerElRef.current || this.props.backupElRef.current, // the element to render into 5615 this.customContentInfo.contentVal); 5616 } 5617 }; 5618 return ContentHookInner; 5619 }(BaseComponent)); 5620 var MountHook = /** @class */ (function (_super) { 5621 __extends(MountHook, _super); 5622 function MountHook() { 5623 var _this = _super !== null && _super.apply(this, arguments) || this; 5624 _this.handleRootEl = function (rootEl) { 5625 _this.rootEl = rootEl; 5626 if (_this.props.elRef) { 5627 setRef(_this.props.elRef, rootEl); 5628 } 5629 }; 5630 return _this; 5631 } 5632 MountHook.prototype.render = function () { 5633 return this.props.children(this.handleRootEl); 5634 }; 5635 MountHook.prototype.componentDidMount = function () { 5636 var callback = this.props.didMount; 5637 if (callback) { 5638 callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl })); 5639 } 5640 }; 5641 MountHook.prototype.componentWillUnmount = function () { 5642 var callback = this.props.willUnmount; 5643 if (callback) { 5644 callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl })); 5645 } 5646 }; 5647 return MountHook; 5648 }(BaseComponent)); 5649 function buildClassNameNormalizer() { 5650 var currentGenerator; 5651 var currentHookProps; 5652 var currentClassNames = []; 5653 return function (generator, hookProps) { 5654 if (!currentHookProps || !isPropsEqual(currentHookProps, hookProps) || generator !== currentGenerator) { 5655 currentGenerator = generator; 5656 currentHookProps = hookProps; 5657 currentClassNames = normalizeClassNames(generator, hookProps); 5658 } 5659 return currentClassNames; 5660 }; 5661 } 5662 function normalizeClassNames(classNames, hookProps) { 5663 if (typeof classNames === 'function') { 5664 classNames = classNames(hookProps); 5665 } 5666 return parseClassNames(classNames); 5667 } 5668 function normalizeContent(input, hookProps) { 5669 if (typeof input === 'function') { 5670 return input(hookProps, createElement); // give the function the vdom-creation func 5671 } 5672 return input; 5673 } 5674 5675 var ViewRoot = /** @class */ (function (_super) { 5676 __extends(ViewRoot, _super); 5677 function ViewRoot() { 5678 var _this = _super !== null && _super.apply(this, arguments) || this; 5679 _this.normalizeClassNames = buildClassNameNormalizer(); 5680 return _this; 5681 } 5682 ViewRoot.prototype.render = function () { 5683 var _a = this, props = _a.props, context = _a.context; 5684 var options = context.options; 5685 var hookProps = { view: context.viewApi }; 5686 var customClassNames = this.normalizeClassNames(options.viewClassNames, hookProps); 5687 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)); })); 5688 }; 5689 return ViewRoot; 5690 }(BaseComponent)); 5691 5692 function parseViewConfigs(inputs) { 5693 return mapHash(inputs, parseViewConfig); 5694 } 5695 function parseViewConfig(input) { 5696 var rawOptions = typeof input === 'function' ? 5697 { component: input } : 5698 input; 5699 var component = rawOptions.component; 5700 if (rawOptions.content) { 5701 component = createViewHookComponent(rawOptions); 5702 // TODO: remove content/classNames/didMount/etc from options? 5703 } 5704 return { 5705 superType: rawOptions.type, 5706 component: component, 5707 rawOptions: rawOptions, 5708 }; 5709 } 5710 function createViewHookComponent(options) { 5711 return function (viewProps) { return (createElement(ViewContextType.Consumer, null, function (context) { return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (viewElRef, viewClassNames) { 5712 var hookProps = __assign(__assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold }); 5713 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
5713oncat(customClassNames).join(' '), ref: rootElRef }, innerContent)); })); 5714 })); })); }; 5715 } 5716 5717 function buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) { 5718 var defaultConfigs = parseViewConfigs(defaultInputs); 5719 var overrideConfigs = parseViewConfigs(optionOverrides.views); 5720 var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs); 5721 return mapHash(viewDefs, function (viewDef) { return buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults); }); 5722 } 5723 function buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) { 5724 var durationInput = viewDef.overrides.duration || 5725 viewDef.defaults.duration || 5726 dynamicOptionOverrides.duration || 5727 optionOverrides.duration; 5728 var duration = null; 5729 var durationUnit = ''; 5730 var singleUnit = ''; 5731 var singleUnitOverrides = {}; 5732 if (durationInput) { 5733 duration = createDurationCached(durationInput); 5734 if (duration) { // valid? 5735 var denom = greatestDurationDenominator(duration); 5736 durationUnit = denom.unit; 5737 if (denom.value === 1) { 5738 singleUnit = durationUnit; 5739 singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {}; 5740 } 5741 } 5742 } 5743 var queryButtonText = function (optionsSubset) { 5744 var buttonTextMap = optionsSubset.buttonText || {}; 5745 var buttonTextKey = viewDef.defaults.buttonTextKey; 5746 if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) { 5747 return buttonTextMap[buttonTextKey]; 5748 } 5749 if (buttonTextMap[viewDef.type] != null) { 5750 return buttonTextMap[viewDef.type]; 5751 } 5752 if (buttonTextMap[singleUnit] != null) { 5753 return buttonTextMap[singleUnit]; 5754 } 5755 return null; 5756 }; 5757 var queryButtonTitle = function (optionsSubset) { 5758 var buttonHints = optionsSubset.buttonHints || {}; 5759 var buttonKey = viewDef.defaults.buttonTextKey; // use same key as text 5760 if (buttonKey != null && buttonHints[buttonKey] != null) { 5761 return buttonHints[buttonKey]; 5762 } 5763 if (buttonHints[viewDef.type] != null) { 5764 return buttonHints[viewDef.type]; 5765 } 5766 if (buttonHints[singleUnit] != null) { 5767 return buttonHints[singleUnit]; 5768 } 5769 return null; 5770 }; 5771 return { 5772 type: viewDef.type, 5773 component: viewDef.component, 5774 duration: duration, 5775 durationUnit: durationUnit, 5776 singleUnit: singleUnit, 5777 optionDefaults: viewDef.defaults, 5778 optionOverrides: __assign(__assign({}, singleUnitOverrides), viewDef.overrides), 5779 buttonTextOverride: queryButtonText(dynamicOptionOverrides) || 5780 queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence 5781 viewDef.overrides.buttonText, 5782 buttonTextDefault: queryButtonText(localeDefaults) || 5783 viewDef.defaults.buttonText || 5784 queryButtonText(BASE_OPTION_DEFAULTS) || 5785 viewDef.type, 5786 // not DRY 5787 buttonTitleOverride: queryButtonTitle(dynamicOptionOverrides) || 5788 queryButtonTitle(optionOverrides) || 5789 viewDef.overrides.buttonHint, 5790 buttonTitleDefault: queryButtonTitle(localeDefaults) || 5791 viewDef.defaults.buttonHint || 5792 queryButtonTitle(BASE_OPTION_DEFAULTS), 5793 // will eventually fall back to buttonText 5794 }; 5795 } 5796 // hack to get memoization working 5797 var durationInputMap = {}; 5798 function createDurationCached(durationInput) { 5799 var json = JSON.stringify(durationInput); 5800 var res = durationInputMap[json]; 5801 if (res === undefined) { 5802 res = createDuration(durationInput); 5803 durationInputMap[json] = res; 5804 } 5805 return res; 5806 } 5807 5808 var DateProfileGenerator = /** @class */ (function () { 5809 function DateProfileGenerator(props) { 5810 this.props = props; 5811 this.nowDate = getNow(props.nowInput, props.dateEnv); 5812 this.initHiddenDays(); 5813 } 5814 /* Date Range Computation 5815 ------------------------------------------------------------------------------------------------------------------*/ 5816 // Builds a structure with info about what the dates/ranges will be for the "prev" view. 5817 DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate, forceToValid) { 5818 var dateEnv = this.props.dateEnv; 5819 var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 5820 currentDateProfile.dateIncrement); 5821 return this.build(prevDate, -1, forceToValid); 5822 }; 5823 // Builds a structure with info about what the dates/ranges will be for the "next" view. 5824 DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate, forceToValid) { 5825 var dateEnv = this.props.dateEnv; 5826 var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 5827 currentDateProfile.dateIncrement); 5828 return this.build(nextDate, 1, forceToValid); 5829 }; 5830 // Builds a structure holding dates/ranges for rendering around the given date. 5831 // Optional direction param indicates whether the date is being incremented/decremented 5832 // from its previous value. decremented = -1, incremented = 1 (default). 5833 DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) { 5834 if (forceToValid === void 0) { forceToValid = true; } 5835 var props = this.props;
5836 var validRange; 5837 var currentInfo; 5838 var isRangeAllDay; 5839 var renderRange; 5840 var activeRange; 5841 var isValid; 5842 validRange = this.buildValidRange(); 5843 validRange = this.trimHiddenDays(validRange); 5844 if (forceToValid) { 5845 currentDate = constrainMarkerToRange(currentDate, validRange); 5846 } 5847 currentInfo = this.buildCurrentRangeInfo(currentDate, direction); 5848 isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit); 5849 renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay); 5850 renderRange = this.trimHiddenDays(renderRange); 5851 activeRange = renderRange; 5852 if (!props.showNonCurrentDates) { 5853 activeRange = intersectRanges(activeRange, currentInfo.range); 5854 } 5855 activeRange = this.adjustActiveRange(activeRange); 5856 activeRange = intersectRanges(activeRange, validRange); // might return null 5857 // it's invalid if the originally requested date is not contained, 5858 // or if the range is completely outside of the valid range. 5859 isValid = rangesIntersect(currentInfo.range, validRange); 5860 return { 5861 // constraint for where prev/next operations can go and where events can be dragged/resized to. 5862 // an object with optional start and end properties. 5863 validRange: validRange, 5864 // range the view is formally responsible for. 5865 // for example, a month view might have 1st-31st, excluding padded dates 5866 currentRange: currentInfo.range, 5867 // name of largest unit being displayed, like "month" or "week" 5868 currentRangeUnit: currentInfo.unit, 5869 isRangeAllDay: isRangeAllDay, 5870 // dates that display events and accept drag-n-drop 5871 // will be `null` if no dates accept events 5872 activeRange: activeRange, 5873 // date range with a rendered skeleton 5874 // includes not-active days that need some sort of DOM 5875 renderRange: renderRange, 5876 // Duration object that denotes the first visible time of any given day 5877 slotMinTime: props.slotMinTime, 5878 // Duration object that denotes the exclusive visible end time of any given day 5879 slotMaxTime: props.slotMaxTime, 5880 isValid: isValid, 5881 // how far the current date will move for a prev/next operation 5882 dateIncrement: this.buildDateIncrement(currentInfo.duration), 5883 // pass a fallback (might be null) ^ 5884 }; 5885 }; 5886 // Builds an object with optional start/end properties. 5887 // Indicates the minimum/maximum dates to display. 5888 // not responsible for trimming hidden days. 5889 DateProfileGenerator.prototype.buildValidRange = function () { 5890 var input = this.props.validRangeInput; 5891 var simpleInput = typeof input === 'function' 5892 ? input.call(this.props.calendarApi, this.nowDate) 5893 : input; 5894 return this.refineRange(simpleInput) || 5895 { start: null, end: null }; // completely open-ended 5896 }; 5897 // Builds a structure with info about the "current" range, the range that is 5898 // highlighted as being the current month for example. 5899 // See build() for a description of `direction`. 5900 // Guaranteed to have `range` and `unit` properties. `duration` is optional. 5901 DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) { 5902 var props = this.props; 5903 var duration = null; 5904 var unit = null; 5905 var range = null; 5906 var dayCount; 5907 if (props.duration) { 5908 duration = props.duration; 5909 unit = props.durationUnit; 5910 range = this.buildRangeFromDuration(date, direction, duration, unit); 5911 } 5912 else if ((dayCount = this.props.dayCount)) { 5913 unit = 'day'; 5914 range = this.buildRangeFromDayCount(date, direction, dayCount); 5915 } 5916 else if ((range = this.buildCustomVisibleRange(date))) { 5917 unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit; 5918 } 5919 else { 5920 duration = this.getFallbackDuration(); 5921 unit = greatestDurationDenominator(duration).unit; 5922 range = this.buildRangeFromDuration(date, direction, duration, unit); 5923 } 5924 return { duration: duration, unit: unit, range: range }; 5925 }; 5926 DateProfileGenerator.prototype.getFallbackDuration = function () { 5927 return createDuration({ day: 1 }); 5928 }; 5929 // Returns a new activeRange to have time values (un-ambiguate) 5930 // slotMinTime or slotMaxTime causes the range to expand. 5931 DateProfileGenerator.prototype.adjustActiveRange = function (range) { 5932 var _a = this.props, dateEnv = _a.dateEnv, usesMinMaxTime = _a.usesMinMaxTime, slotMinTime = _a.slotMinTime, slotMaxTime = _a.slotMaxTime; 5933 var start = range.start, end = range.end; 5934 if (usesMinMaxTime) { 5935 // expand active range if slotMinTime is negative (why not when positive?) 5936 if (asRoughDays(slotMinTime) < 0) { 5937 start = startOfDay(start); // necessary? 5938 start = dateEnv.add(start, slotMinTime); 5939 } 5940 // expand active range if slotMaxTime is beyond one day (why not when negative?) 5941 if (asRoughDays(slotMaxTime) > 1) { 5942 end = startOfDay(end); // necessary? 5943 end = addDays(end, -1);
5944 end = dateEnv.add(end, slotMaxTime); 5945 } 5946 } 5947 return { start: start, end: end }; 5948 }; 5949 // Builds the "current" range when it is specified as an explicit duration. 5950 // `unit` is the already-computed greatestDurationDenominator unit of duration. 5951 DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) { 5952 var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment; 5953 var start; 5954 var end; 5955 var res; 5956 // compute what the alignment should be 5957 if (!dateAlignment) { 5958 var dateIncrement = this.props.dateIncrement; 5959 if (dateIncrement) { 5960 // use the smaller of the two units 5961 if (asRoughMs(dateIncrement) < asRoughMs(duration)) { 5962 dateAlignment = greatestDurationDenominator(dateIncrement).unit; 5963 } 5964 else { 5965 dateAlignment = unit; 5966 } 5967 } 5968 else { 5969 dateAlignment = unit; 5970 } 5971 } 5972 // if the view displays a single day or smaller 5973 if (asRoughDays(duration) <= 1) { 5974 if (this.isHiddenDay(start)) { 5975 start = this.skipHiddenDays(start, direction); 5976 start = startOfDay(start); 5977 } 5978 } 5979 function computeRes() { 5980 start = dateEnv.startOf(date, dateAlignment); 5981 end = dateEnv.add(start, duration); 5982 res = { start: start, end: end }; 5983 } 5984 computeRes(); 5985 // if range is completely enveloped by hidden days, go past the hidden days 5986 if (!this.trimHiddenDays(res)) { 5987 date = this.skipHiddenDays(date, direction); 5988 computeRes(); 5989 } 5990 return res; 5991 }; 5992 // Builds the "current" range when a dayCount is specified. 5993 DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) { 5994 var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment; 5995 var runningCount = 0; 5996 var start = date; 5997 var end; 5998 if (dateAlignment) { 5999 start = dateEnv.startOf(start, dateAlignment); 6000 } 6001 start = startOfDay(start); 6002 start = this.skipHiddenDays(start, direction); 6003 end = start; 6004 do { 6005 end = addDays(end, 1); 6006 if (!this.isHiddenDay(end)) { 6007 runningCount += 1; 6008 } 6009 } while (runningCount < dayCount); 6010 return { start: start, end: end }; 6011 }; 6012 // Builds a normalized range object for the "visible" range, 6013 // which is a way to define the currentRange and activeRange at the same time. 6014 DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) { 6015 var props = this.props; 6016 var input = props.visibleRangeInput; 6017 var simpleInput = typeof input === 'function' 6018 ? input.call(props.calendarApi, props.dateEnv.toDate(date)) 6019 : input; 6020 var range = this.refineRange(simpleInput); 6021 if (range && (range.start == null || range.end == null)) { 6022 return null; 6023 } 6024 return range; 6025 }; 6026 // Computes the range that will represent the element/cells for *rendering*, 6027 // but which may have voided days/times. 6028 // not responsible for trimming hidden days. 6029 DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) { 6030 return currentRange; 6031 }; 6032 // Compute the duration value that should be added/substracted to the current date 6033 // when a prev/next operation happens. 6034 DateProfileGenerator.prototype.buildDateIncrement = function (fallback) { 6035 var dateIncrement = this.props.dateIncrement; 6036 var customAlignment; 6037 if (dateIncrement) { 6038 return dateIncrement; 6039 } 6040 if ((customAlignment = this.props.dateAlignment)) { 6041 return createDuration(1, customAlignment); 6042 } 6043 if (fallback) { 6044 return fallback; 6045 } 6046 return createDuration({ days: 1 }); 6047 }; 6048 DateProfileGenerator.prototype.refineRange = function (rangeInput) { 6049 if (rangeInput) { 6050 var range = parseRange(rangeInput, this.props.dateEnv); 6051 if (range) { 6052 range = computeVisibleDayRange(range); 6053 } 6054 return range; 6055 } 6056 return null; 6057 }; 6058 /* Hidden Days 6059 ------------------------------------------------------------------------------------------------------------------*/ 6060 // Initializes internal variables related to calculating hidden days-of-week 6061 DateProfileGenerator.prototype.initHiddenDays = function () { 6062 var hiddenDays = this.props.hiddenDays || []; // array of day-of-week indices that are hidden
6063 var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool) 6064 var dayCnt = 0; 6065 var i; 6066 if (this.props.weekends === false) { 6067 hiddenDays.push(0, 6); // 0=sunday, 6=saturday 6068 } 6069 for (i = 0; i < 7; i += 1) { 6070 if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) { 6071 dayCnt += 1; 6072 } 6073 } 6074 if (!dayCnt) { 6075 throw new Error('invalid hiddenDays'); // all days were hidden? bad. 6076 } 6077 this.isHiddenDayHash = isHiddenDayHash; 6078 }; 6079 // Remove days from the beginning and end of the range that are computed as hidden. 6080 // If the whole range is trimmed off, returns null 6081 DateProfileGenerator.prototype.trimHiddenDays = function (range) { 6082 var start = range.start, end = range.end; 6083 if (start) { 6084 start = this.skipHiddenDays(start); 6085 } 6086 if (end) { 6087 end = this.skipHiddenDays(end, -1, true); 6088 } 6089 if (start == null || end == null || start < end) { 6090 return { start: start, end: end }; 6091 } 6092 return null; 6093 }; 6094 // Is the current day hidden? 6095 // `day` is a day-of-week index (0-6), or a Date (used for UTC) 6096 DateProfileGenerator.prototype.isHiddenDay = function (day) { 6097 if (day instanceof Date) { 6098 day = day.getUTCDay(); 6099 } 6100 return this.isHiddenDayHash[day]; 6101 }; 6102 // Incrementing the current day until it is no longer a hidden day, returning a copy. 6103 // DOES NOT CONSIDER validRange! 6104 // If the initial value of `date` is not a hidden day, don't do anything. 6105 // Pass `isExclusive` as `true` if you are dealing with an end date. 6106 // `inc` defaults to `1` (increment one day forward each time) 6107 DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) { 6108 if (inc === void 0) { inc = 1; } 6109 if (isExclusive === void 0) { isExclusive = false; } 6110 while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) { 6111 date = addDays(date, inc); 6112 } 6113 return date; 6114 }; 6115 return DateProfileGenerator; 6116 }()); 6117 6118 function reduceViewType(viewType, action) { 6119 switch (action.type) { 6120 case 'CHANGE_VIEW_TYPE': 6121 viewType = action.viewType; 6122 } 6123 return viewType; 6124 } 6125 6126 function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) { 6127 var _a; 6128 switch (action.type) { 6129 case 'SET_OPTION': 6130 return __assign(__assign({}, dynamicOptionOverrides), (_a = {}, _a[action.optionName] = action.rawOptionValue, _a)); 6131 default: 6132 return dynamicOptionOverrides; 6133 } 6134 } 6135 6136 function reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) { 6137 var dp; 6138 switch (action.type) { 6139 case 'CHANGE_VIEW_TYPE': 6140 return dateProfileGenerator.build(action.dateMarker || currentDate); 6141 case 'CHANGE_DATE': 6142 return dateProfileGenerator.build(action.dateMarker); 6143 case 'PREV': 6144 dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate); 6145 if (dp.isValid) { 6146 return dp; 6147 } 6148 break; 6149 case 'NEXT': 6150 dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate); 6151 if (dp.isValid) { 6152 return dp; 6153 } 6154 break; 6155 } 6156 return currentDateProfile; 6157 } 6158 6159 function initEventSources(calendarOptions, dateProfile, context) { 6160 var activeRange = dateProfile ? dateProfile.activeRange : null; 6161 return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context); 6162 } 6163 function reduceEventSources(eventSources, action, dateProfile, context) { 6164 var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check? 6165 switch (action.type) { 6166 case 'ADD_EVENT_SOURCES': // already parsed 6167 return addSources(eventSources, action.sources, activeRange, context);
6168 case 'REMOVE_EVENT_SOURCE': 6169 return removeSource(eventSources, action.sourceId); 6170 case 'PREV': // TODO: how do we track all actions that affect dateProfile :( 6171 case 'NEXT': 6172 case 'CHANGE_DATE': 6173 case 'CHANGE_VIEW_TYPE': 6174 if (dateProfile) { 6175 return fetchDirtySources(eventSources, activeRange, context); 6176 } 6177 return eventSources; 6178 case 'FETCH_EVENT_SOURCES': 6179 return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type? 6180 arrayToHash(action.sourceIds) : 6181 excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context); 6182 case 'RECEIVE_EVENTS': 6183 case 'RECEIVE_EVENT_ERROR': 6184 return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange); 6185 case 'REMOVE_ALL_EVENT_SOURCES': 6186 return {}; 6187 default: 6188 return eventSources; 6189 } 6190 } 6191 function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) { 6192 var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check? 6193 return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context); 6194 } 6195 function computeEventSourcesLoading(eventSources) { 6196 for (var sourceId in eventSources) { 6197 if (eventSources[sourceId].isFetching) { 6198 return true; 6199 } 6200 } 6201 return false; 6202 } 6203 function addSources(eventSourceHash, sources, fetchRange, context) { 6204 var hash = {}; 6205 for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) { 6206 var source = sources_1[_i]; 6207 hash[source.sourceId] = source; 6208 } 6209 if (fetchRange) { 6210 hash = fetchDirtySources(hash, fetchRange, context); 6211 } 6212 return __assign(__assign({}, eventSourceHash), hash); 6213 } 6214 function removeSource(eventSourceHash, sourceId) { 6215 return filterHash(eventSourceHash, function (eventSource) { return eventSource.sourceId !== sourceId; }); 6216 } 6217 function fetchDirtySources(sourceHash, fetchRange, context) { 6218 return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) { return isSourceDirty(eventSource, fetchRange, context); }), fetchRange, false, context); 6219 } 6220 function isSourceDirty(eventSource, fetchRange, context) { 6221 if (!doesSourceNeedRange(eventSource, context)) { 6222 return !eventSource.latestFetchId; 6223 } 6224 return !context.options.lazyFetching || 6225 !eventSource.fetchRange || 6226 eventSource.isFetching || // always cancel outdated in-progress fetches 6227 fetchRange.start < eventSource.fetchRange.start || 6228 fetchRange.end > eventSource.fetchRange.end; 6229 } 6230 function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) { 6231 var nextSources = {}; 6232 for (var sourceId in prevSources) { 6233 var source = prevSources[sourceId]; 6234 if (sourceIdHash[sourceId]) { 6235 nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context); 6236 } 6237 else { 6238 nextSources[sourceId] = source; 6239 } 6240 } 6241 return nextSources; 6242 } 6243 function fetchSource(eventSource, fetchRange, isRefetch, context) { 6244 var options = context.options, calendarApi = context.calendarApi; 6245 var sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId]; 6246 var fetchId = guid(); 6247 sourceDef.fetch({ 6248 eventSource: eventSource, 6249 range: fetchRange, 6250 isRefetch: isRefetch, 6251 context: context, 6252 }, function (res) { 6253 var rawEvents = res.rawEvents; 6254 if (options.eventSourceSuccess) { 6255 rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.xhr) || rawEvents; 6256 } 6257 if (eventSource.success) { 6258 rawEvents = eventSource.success.call(calendarApi, rawEvents, res.xhr) || rawEvents; 6259 } 6260 context.dispatch({ 6261 type: 'RECEIVE_EVENTS', 6262 sourceId: eventSource.sourceId, 6263 fetchId: fetchId, 6264 fetchRange: fetchRange, 6265 rawEvents: rawEvents, 6266 }); 6267 }, function (error) { 6268 console.warn(error.message, error); 6269 if (options.eventSourceFailure) { 6270 options.eventSourceFailure.call(calendarApi, error); 6271 } 6272 if (eventSource.failure) { 6273 eventSource.failure(error); 6274 } 6275 context.dispatch({ 6276 type: 'RECEIVE_EVENT_ERROR', 6277 sourceId: eventSource.sourceId, 6278 fetchId: fetchId, 6279 fetchRange: fetchRange, 6280 error: error, 6281 }); 6282 }); 6283 return __assign(__assign({}, eventSource), { isFetching: true, latestFetchId: fetchId }); 6284 } 6285 function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) { 6286 var _a; 6287 var eventSource = sourceHash[sourceId]; 6288 if (eventSource && // not already removed 6289 fetchId === eventSource.latestFetchId) { 6290 return __assign(__assign({}, sourceHash), (_a = {}, _a[sourceId] = __assign(__assign({}, eventSource), { isFetching: false, fetchRange: fetchRange }), _a)); 6291 } 6292 return sourceHash; 6293 } 6294 function excludeStaticSources(eventSources, context) { 6295 return filterHash(eventSources, function (eventSource) { return doesSourceNeedRange(eventSource, context); }); 6296 } 6297 function parseInitialSources(rawOptions, context) { 6298 var refiners = buildEventSourceRefiners(context); 6299 var rawSources = [].concat(rawOptions.eventSources || []); 6300 var sources = []; // parsed 6301 if (rawOptions.initialEvents) { 6302 rawSources.unshift(rawOptions.initialEvents); 6303 } 6304 if (rawOptions.events) { 6305 rawSources.unshift(rawOptions.events); 6306 } 6307 for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) { 6308 var rawSource = rawSources_1[_i]; 6309 var source = parseEventSource(rawSource, context, refiners); 6310 if (source) { 6311 sources.push(source); 6312 } 6313 } 6314 return sources; 6315 } 6316 function doesSourceNeedRange(eventSource, context) { 6317 var defs = context.pluginHooks.eventSourceDefs; 6318 return !defs[eventSource.sourceDefId].ignoreRange; 6319 } 6320 6321 function reduceEventStore(eventStore, action, eventSources, dateProfile, context) { 6322 switch (action.type) { 6323 case 'RECEIVE_EVENTS': // raw 6324 return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context); 6325 case 'ADD_EVENTS': // already parsed, but not expanded 6326 return addEvent(eventStore, action.eventStore, // new ones 6327 dateProfile ? dateProfile.activeRange : null, context); 6328 case 'RESET_EVENTS': 6329 return action.eventStore; 6330 case 'MERGE_EVENTS': // already parsed and expanded 6331 return mergeEventStores(eventStore, action.eventStore); 6332 case 'PREV': // TODO: how do we track all actions that affect dateProfile :( 6333 case 'NEXT': 6334 case 'CHANGE_DATE': 6335 case 'CHANGE_VIEW_TYPE': 6336 if (dateProfile) { 6337 return expandRecurring(eventStore, dateProfile.activeRange, context); 6338 } 6339 return eventStore;
6340 case 'REMOVE_EVENTS': 6341 return excludeSubEventStore(eventStore, action.eventStore); 6342 case 'REMOVE_EVENT_SOURCE': 6343 return excludeEventsBySourceId(eventStore, action.sourceId); 6344 case 'REMOVE_ALL_EVENT_SOURCES': 6345 return filterEventStoreDefs(eventStore, function (eventDef) { return (!eventDef.sourceId // only keep events with no source id 6346 ); }); 6347 case 'REMOVE_ALL_EVENTS': 6348 return createEmptyEventStore(); 6349 default: 6350 return eventStore; 6351 } 6352 } 6353 function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) { 6354 if (eventSource && // not already removed 6355 fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources 6356 ) { 6357 var subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context); 6358 if (fetchRange) { 6359 subset = expandRecurring(subset, fetchRange, context); 6360 } 6361 return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset); 6362 } 6363 return eventStore; 6364 } 6365 function transformRawEvents(rawEvents, eventSource, context) { 6366 var calEachTransform = context.options.eventDataTransform; 6367 var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null; 6368 if (sourceEachTransform) { 6369 rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform); 6370 } 6371 if (calEachTransform) { 6372 rawEvents = transformEachRawEvent(rawEvents, calEachTransform); 6373 } 6374 return rawEvents; 6375 } 6376 function transformEachRawEvent(rawEvents, func) { 6377 var refinedEvents; 6378 if (!func) { 6379 refinedEvents = rawEvents; 6380 } 6381 else { 6382 refinedEvents = []; 6383 for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) { 6384 var rawEvent = rawEvents_1[_i]; 6385 var refinedEvent = func(rawEvent); 6386 if (refinedEvent) { 6387 refinedEvents.push(refinedEvent); 6388 } 6389 else if (refinedEvent == null) { 6390 refinedEvents.push(rawEvent); 6391 } // if a different falsy value, do nothing 6392 } 6393 } 6394 return refinedEvents; 6395 } 6396 function addEvent(eventStore, subset, expandRange, context) { 6397 if (expandRange) { 6398 subset = expandRecurring(subset, expandRange, context); 6399 } 6400 return mergeEventStores(eventStore, subset); 6401 } 6402 function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) { 6403 var defs = eventStore.defs; 6404 var instances = mapHash(eventStore.instances, function (instance) { 6405 var def = defs[instance.defId]; 6406 if (def.allDay || def.recurringDef) { 6407 return instance; // isn't dependent on timezone 6408 } 6409 return __assign(__assign({}, instance), { range: { 6410 start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)), 6411 end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo)), 6412 }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo }); 6413 }); 6414 return { defs: defs, instances: instances }; 6415 } 6416 function excludeEventsBySourceId(eventStore, sourceId) { 6417 return filterEventStoreDefs(eventStore, function (eventDef) { return eventDef.sourceId !== sourceId; }); 6418 } 6419 // QUESTION: why not just return instances? do a general object-property-exclusion util 6420 function excludeInstances(eventStore, removals) { 6421 return { 6422 defs: eventStore.defs, 6423 instances: filterHash(eventStore.instances, function (instance) { return !removals[instance.instanceId]; }), 6424 }; 6425 } 6426 6427 function reduceDateSelection(currentSelection, action) { 6428 switch (action.type) { 6429 case 'UNSELECT_DATES': 6430 return null; 6431 case 'SELECT_DATES': 6432 return action.selection; 6433 default: 6434 return currentSelection; 6435 } 6436 } 6437 6438 function reduceSelectedEvent(currentInstanceId, action) { 6439 switch (action.type) { 6440 case 'UNSELECT_EVENT': 6441 return ''; 6442 case 'SELECT_EVENT': 6443 return action.eventInstanceId; 6444 default: 6445 return currentInstanceId; 6446 } 6447 } 6448 6449 function reduceEventDrag(currentDrag, action) { 6450 var newDrag; 6451 switch (action.type) { 6452 case 'UNSET_EVENT_DRAG': 6453 return null; 6454 case 'SET_EVENT_DRAG': 6455 newDrag = action.state; 6456 return { 6457 affectedEvents: newDrag.affectedEvents, 6458 mutatedEvents: newDrag.mutatedEvents, 6459 isEvent: newDrag.isEvent, 6460 }; 6461 default: 6462 return currentDrag; 6463 } 6464 } 6465 6466 function reduceEventResize(currentResize, action) { 6467 var newResize; 6468 switch (action.type) { 6469 case 'UNSET_EVENT_RESIZE': 6470 return null; 6471 case 'SET_EVENT_RESIZE': 6472 newResize = action.state; 6473 return { 6474 affectedEvents: newResize.affectedEvents, 6475 mutatedEvents: newResize.mutatedEvents, 6476 isEvent: newResize.isEvent, 6477 }; 6478 default: 6479 return currentResize; 6480 } 6481 } 6482 6483 function parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) { 6484 var header = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null; 6485 var footer = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null; 6486 return { header: header, footer: footer }; 6487 } 6488 function parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) { 6489 var sectionWidgets = {}; 6490 var viewsWithButtons = []; 6491 var hasTitle = false; 6492 for (var sectionName in sectionStrHash) { 6493 var sectionStr = sectionStrHash[sectionName]; 6494 var sectionRes = parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi); 6495 sectionWidgets[sectionName] = sectionRes.widgets; 6496 viewsWithButtons.push.apply(viewsWithButtons, sectionRes.viewsWithButtons); 6497 hasTitle = hasTitle || sectionRes.hasTitle; 6498 } 6499 return { sectionWidgets: sectionWidgets, viewsWithButtons: viewsWithButtons, hasTitle: hasTitle }; 6500 } 6501 /* 6502 BAD: querying icons and text here. should be done at render time 6503 */ 6504 function parseSection(sectionStr, calendarOptions, // defaults+overrides, then refined 6505 calendarOptionOverrides, // overrides only!, unrefined :( 6506 theme, viewSpecs, calendarApi) { 6507 var isRtl = calendarOptions.direction === 'rtl'; 6508 var calendarCustomButtons = calendarOptions.customButtons || {}; 6509 var calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {}; 6510 var calendarButtonText = calendarOptions.buttonText || {}; 6511 var calendarButtonHintOverrides = calendarOptionOverrides.buttonHints || {}; 6512 var calendarButtonHints = calendarOptions.buttonHints || {}; 6513 var sectionSubstrs = sectionStr ? sectionStr.split(' ') : []; 6514 var viewsWithButtons = []; 6515 var hasTitle = false; 6516 var widgets = sectionSubstrs.map(function (buttonGroupStr) { return (buttonGroupStr.split(',').map(function (buttonName) { 6517 if (buttonName === 'title') { 6518 hasTitle = true; 6519 return { buttonName: buttonName }; 6520 } 6521 var customButtonProps; 6522 var viewSpec; 6523 var buttonClick; 6524 var buttonIcon; // only one of these will be set 6525 var buttonText; // " 6526 var buttonHint; 6527 // ^ for the title="" attribute, for accessibility 6528 if ((customButtonProps = calendarCustomButtons[buttonName])) { 6529 buttonClick = function (ev) { 6530 if (customButtonProps.click) { 6531 customButtonProps.click.call(ev.target, ev, ev.target); // TODO: use Calendar this context? 6532 } 6533 }; 6534 (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) || 6535 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6536 (buttonText = customButtonProps.text); 6537 buttonHint = customButtonProps.hint || customButtonProps.text; 6538 } 6539 else if ((viewSpec = viewSpecs[buttonName])) { 6540 viewsWithButtons.push(buttonName); 6541 buttonClick = function () { 6542 calendarApi.changeView(buttonName); 6543 }; 6544 (buttonText = viewSpec.buttonTextOverride) || 6545 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6546 (buttonText = viewSpec.buttonTextDefault); 6547 var textFallback = viewSpec.buttonTextOverride || 6548 viewSpec.buttonTextDefault; 6549 buttonHint = formatWithOrdinals(viewSpec.buttonTitleOverride || 6550 viewSpec.buttonTitleDefault || 6551 calendarOptions.viewHint, [textFallback, buttonName], // view-name = buttonName 6552 textFallback); 6553 } 6554 else if (calendarApi[buttonName]) { // a calendarApi method 6555 buttonClick = function () { 6556 calendarApi[buttonName](); 6557 }; 6558 (buttonText = calendarButtonTextOverrides[buttonName]) || 6559 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6560 (buttonText = calendarButtonText[buttonName]); // everything else is considered default 6561 if (buttonName === 'prevYear' || buttonName === 'nextYear') { 6562 var prevOrNext = buttonName === 'prevYear' ? 'prev' : 'next'; 6563 buttonHint = formatWithOrdinals(calendarButtonHintOverrides[prevOrNext] || 6564 calendarButtonHints[prevOrNext], [ 6565 calendarButtonText.year || 'year', 6566 'year', 6567 ], calendarButtonText[buttonName]); 6568 } 6569 else { 6570 buttonHint = function (navUnit) { return formatWithOrdinals(calendarButtonHintOverrides[buttonName] || 6571 calendarButtonHints[buttonName], [ 6572 calendarButtonText[navUnit] || navUnit, 6573 navUnit, 6574 ], calendarButtonText[buttonName]); }; 6575 } 6576 } 6577 return { buttonName: buttonName, buttonClick: buttonClick, buttonIcon: buttonIcon, buttonText: buttonText, buttonHint: buttonHint }; 6578 })); }); 6579 return { widgets: widgets, viewsWithButtons: viewsWithButtons, hasTitle: hasTitle }; 6580 } 6581 6582 var eventSourceDef$3 = { 6583 ignoreRange: true, 6584 parseMeta: function (refined) { 6585 if (Array.isArray(refined.events)) { 6586 return refined.events; 6587 } 6588 return null; 6589 }, 6590 fetch: function (arg, success) { 6591 success({ 6592 rawEvents: arg.eventSource.meta, 6593 }); 6594 }, 6595 }; 6596 var arrayEventSourcePlugin = createPlugin({ 6597 eventSourceDefs: [eventSourceDef$3], 6598 });
6599 6600 var eventSourceDef$2 = { 6601 parseMeta: function (refined) { 6602 if (typeof refined.events === 'function') { 6603 return refined.events; 6604 } 6605 return null; 6606 }, 6607 fetch: function (arg, success, failure) { 6608 var dateEnv = arg.context.dateEnv; 6609 var func = arg.eventSource.meta; 6610 unpromisify(func.bind(null, buildRangeApiWithTimeZone(arg.range, dateEnv)), function (rawEvents) { 6611 success({ rawEvents: rawEvents }); // needs an object response 6612 }, failure); 6613 }, 6614 }; 6615 var funcEventSourcePlugin = createPlugin({ 6616 eventSourceDefs: [eventSourceDef$2], 6617 }); 6618 6619 function requestJson(method, url, params, successCallback, failureCallback) { 6620 method = method.toUpperCase(); 6621 var body = null; 6622 if (method === 'GET') { 6623 url = injectQueryStringParams(url, params); 6624 } 6625 else { 6626 body = encodeParams(params); 6627 } 6628 var xhr = new XMLHttpRequest(); 6629 xhr.open(method, url, true); 6630 if (method !== 'GET') { 6631 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 6632 } 6633 xhr.onload = function () { 6634 if (xhr.status >= 200 && xhr.status < 400) { 6635 var parsed = false; 6636 var res = void 0; 6637 try { 6638 res = JSON.parse(xhr.responseText); 6639 parsed = true; 6640 } 6641 catch (err) { 6642 // will handle parsed=false 6643 } 6644 if (parsed) { 6645 successCallback(res, xhr); 6646 } 6647 else { 6648 failureCallback('Failure parsing JSON', xhr); 6649 } 6650 } 6651 else { 6652 failureCallback('Request failed', xhr); 6653 } 6654 }; 6655 xhr.onerror = function () { 6656 failureCallback('Request failed', xhr); 6657 }; 6658 xhr.send(body); 6659 } 6660 function injectQueryStringParams(url, params) { 6661 return url + 6662 (url.indexOf('?') === -1 ? '?' : '&') + 6663 encodeParams(params); 6664 } 6665 function encodeParams(params) { 6666 var parts = []; 6667 for (var key in params) { 6668 parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key])); 6669 } 6670 return parts.join('&'); 6671 } 6672 6673 var JSON_FEED_EVENT_SOURCE_REFINERS = { 6674 method: String, 6675 extraParams: identity, 6676 startParam: String, 6677 endParam: String, 6678 timeZoneParam: String, 6679 }; 6680 6681 var eventSourceDef$1 = { 6682 parseMeta: function (refined) { 6683 if (refined.url && (refined.format === 'json' || !refined.format)) { 6684 return { 6685 url: refined.url, 6686 format: 'json', 6687 method: (refined.method || 'GET').toUpperCase(), 6688 extraParams: refined.extraParams, 6689 startParam: refined.startParam, 6690 endParam: refined.endParam, 6691 timeZoneParam: refined.timeZoneParam, 6692 }; 6693 } 6694 return null; 6695 }, 6696 fetch: function (arg, success, failure) { 6697 var meta = arg.eventSource.meta; 6698 var requestParams = buildRequestParams$1(meta, arg.range, arg.context); 6699 requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) { 6700 success({ rawEvents: rawEvents, xhr: xhr }); 6701 }, function (errorMessage, xhr) { 6702 failure({ message: errorMessage, xhr: xhr }); 6703 }); 6704 }, 6705 }; 6706 var jsonFeedEventSourcePlugin = createPlugin({ 6707 eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS, 6708 eventSourceDefs: [eventSourceDef$1], 6709 }); 6710 function buildRequestParams$1(meta, range, context) { 6711 var dateEnv = context.dateEnv, options = context.options; 6712 var startParam; 6713 var endParam; 6714 var timeZoneParam;
6715 var customRequestParams; 6716 var params = {}; 6717 startParam = meta.startParam; 6718 if (startParam == null) { 6719 startParam = options.startParam; 6720 } 6721 endParam = meta.endParam; 6722 if (endParam == null) { 6723 endParam = options.endParam; 6724 } 6725 timeZoneParam = meta.timeZoneParam; 6726 if (timeZoneParam == null) { 6727 timeZoneParam = options.timeZoneParam; 6728 } 6729 // retrieve any outbound GET/POST data from the options 6730 if (typeof meta.extraParams === 'function') { 6731 // supplied as a function that returns a key/value object 6732 customRequestParams = meta.extraParams(); 6733 } 6734 else { 6735 // probably supplied as a straight key/value object 6736 customRequestParams = meta.extraParams || {}; 6737 } 6738 __assign(params, customRequestParams); 6739 params[startParam] = dateEnv.formatIso(range.start); 6740 params[endParam] = dateEnv.formatIso(range.end); 6741 if (dateEnv.timeZone !== 'local') { 6742 params[timeZoneParam] = dateEnv.timeZone; 6743 } 6744 return params; 6745 } 6746 6747 var SIMPLE_RECURRING_REFINERS = { 6748 daysOfWeek: identity, 6749 startTime: createDuration, 6750 endTime: createDuration, 6751 duration: createDuration, 6752 startRecur: identity, 6753 endRecur: identity, 6754 }; 6755 6756 var recurring = { 6757 parse: function (refined, dateEnv) { 6758 if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) { 6759 var recurringData = { 6760 daysOfWeek: refined.daysOfWeek || null, 6761 startTime: refined.startTime || null, 6762 endTime: refined.endTime || null, 6763 startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null, 6764 endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null, 6765 }; 6766 var duration = void 0; 6767 if (refined.duration) { 6768 duration = refined.duration; 6769 } 6770 if (!duration && refined.startTime && refined.endTime) { 6771 duration = subtractDurations(refined.endTime, refined.startTime); 6772 } 6773 return { 6774 allDayGuess: Boolean(!refined.startTime && !refined.endTime), 6775 duration: duration, 6776 typeData: recurringData, // doesn't need endTime anymore but oh well 6777 }; 6778 } 6779 return null; 6780 }, 6781 expand: function (typeData, framingRange, dateEnv) { 6782 var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur }); 6783 if (clippedFramingRange) { 6784 return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv); 6785 } 6786 return []; 6787 }, 6788 }; 6789 var simpleRecurringEventsPlugin = createPlugin({ 6790 recurringTypes: [recurring], 6791 eventRefiners: SIMPLE_RECURRING_REFINERS, 6792 }); 6793 function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) { 6794 var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null; 6795 var dayMarker = startOfDay(framingRange.start); 6796 var endMarker = framingRange.end; 6797 var instanceStarts = []; 6798 while (dayMarker < endMarker) { 6799 var instanceStart 6800 // if everyday, or this particular day-of-week 6801 = void 0; 6802 // if everyday, or this particular day-of-week 6803 if (!dowHash || dowHash[dayMarker.getUTCDay()]) { 6804 if (startTime) { 6805 instanceStart = dateEnv.add(dayMarker, startTime); 6806 } 6807 else { 6808 instanceStart = dayMarker; 6809 } 6810 instanceStarts.push(instanceStart); 6811 } 6812 dayMarker = addDays(dayMarker, 1); 6813 } 6814 return instanceStarts; 6815 } 6816 6817 var changeHandlerPlugin = createPlugin({ 6818 optionChangeHandlers: { 6819 events: function (events, context) { 6820 handleEventSources([events], context); 6821 }, 6822 eventSources: handleEventSources, 6823 }, 6824 });
6825 /* 6826 BUG: if `event` was supplied, all previously-given `eventSources` will be wiped out 6827 */ 6828 function handleEventSources(inputs, context) { 6829 var unfoundSources = hashValuesToArray(context.getCurrentData().eventSources); 6830 var newInputs = []; 6831 for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) { 6832 var input = inputs_1[_i]; 6833 var inputFound = false; 6834 for (var i = 0; i < unfoundSources.length; i += 1) { 6835 if (unfoundSources[i]._raw === input) { 6836 unfoundSources.splice(i, 1); // delete 6837 inputFound = true; 6838 break; 6839 } 6840 } 6841 if (!inputFound) { 6842 newInputs.push(input); 6843 } 6844 } 6845 for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) { 6846 var unfoundSource = unfoundSources_1[_a]; 6847 context.dispatch({ 6848 type: 'REMOVE_EVENT_SOURCE', 6849 sourceId: unfoundSource.sourceId, 6850 }); 6851 } 6852 for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) { 6853 var newInput = newInputs_1[_b]; 6854 context.calendarApi.addEventSource(newInput); 6855 } 6856 } 6857 6858 function handleDateProfile(dateProfile, context) { 6859 context.emitter.trigger('datesSet', __assign(__assign({}, buildRangeApiWithTimeZone(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi })); 6860 } 6861 6862 function handleEventStore(eventStore, context) { 6863 var emitter = context.emitter; 6864 if (emitter.hasHandlers('eventsSet')) { 6865 emitter.trigger('eventsSet', buildEventApis(eventStore, context)); 6866 } 6867 } 6868 6869 /* 6870 this array is exposed on the root namespace so that UMD plugins can add to it. 6871 see the rollup-bundles script. 6872 */ 6873 var globalPlugins = [ 6874 arrayEventSourcePlugin, 6875 funcEventSourcePlugin, 6876 jsonFeedEventSourcePlugin, 6877 simpleRecurringEventsPlugin, 6878 changeHandlerPlugin, 6879 createPlugin({ 6880 isLoadingFuncs: [ 6881 function (state) { return computeEventSourcesLoading(state.eventSources); }, 6882 ], 6883 contentTypeHandlers: { 6884 html: buildHtmlRenderer, 6885 domNodes: buildDomNodeRenderer, 6886 }, 6887 propSetHandlers: { 6888 dateProfile: handleDateProfile, 6889 eventStore: handleEventStore, 6890 }, 6891 }), 6892 ]; 6893 function buildHtmlRenderer() { 6894 var currentEl = null; 6895 var currentHtml = ''; 6896 function render(el, html) { 6897 if (el !== currentEl || html !== currentHtml) { 6898 el.innerHTML = html; 6899 } 6900 currentEl = el; 6901 currentHtml = html; 6902 } 6903 function destroy() { 6904 currentEl.innerHTML = ''; 6905 currentEl = null; 6906 currentHtml = ''; 6907 } 6908 return { render: render, destroy: destroy }; 6909 } 6910 function buildDomNodeRenderer() { 6911 var currentEl = null; 6912 var currentDomNodes = []; 6913 function render(el, domNodes) { 6914 var newDomNodes = Array.prototype.slice.call(domNodes); 6915 if (el !== currentEl || !isArraysEqual(currentDomNodes, newDomNodes)) { 6916 // append first, remove second (for scroll resetting) 6917 for (var _i = 0, newDomNodes_1 = newDomNodes; _i < newDomNodes_1.length; _i++) { 6918 var newNode = newDomNodes_1[_i]; 6919 el.appendChild(newNode); 6920 } 6921 destroy(); 6922 } 6923 currentEl = el; 6924 currentDomNodes = newDomNodes; 6925 } 6926 function destroy() { 6927 currentDomNodes.forEach(removeElement); 6928 currentDomNodes = []; 6929 currentEl = null; 6930 } 6931 return { render: render, destroy: destroy }; 6932 } 6933 6934 var DelayedRunner = /** @class */ (function () { 6935 function DelayedRunner(drainedOption) { 6936 this.drainedOption = drainedOption; 6937 this.isRunning = false; 6938 this.isDirty = false; 6939 this.pauseDepths = {}; 6940 this.timeoutId = 0; 6941 } 6942 DelayedRunner.prototype.request = function (delay) { 6943 this.isDirty = true; 6944 if (!this.isPaused()) { 6945 this.clearTimeout(); 6946 if (delay == null) { 6947 this.tryDrain(); 6948 } 6949 else { 6950 this.timeoutId = setTimeout(// NOT OPTIMAL! TODO: look at debounce 6951 this.tryDrain.bind(this), delay); 6952 } 6953 } 6954 }; 6955 DelayedRunner.prototype.pause = function (scope) { 6956 if (scope === void 0) { scope = ''; } 6957 var pauseDepths = this.pauseDepths; 6958 pauseDepths[scope] = (pauseDepths[scope] || 0) + 1; 6959 this.clearTimeout(); 6960 }; 6961 DelayedRunner.prototype.resume = function (scope, force) { 6962 if (scope === void 0) { scope = ''; } 6963 var pauseDepths = this.pauseDepths; 6964 if (scope in pauseDepths) { 6965 if (force) { 6966 delete pauseDepths[scope]; 6967 } 6968 else { 6969 pauseDepths[scope] -= 1; 6970 var depth = pauseDepths[scope]; 6971 if (depth <= 0) { 6972 delete pauseDepths[scope]; 6973 } 6974 } 6975 this.tryDrain(); 6976 } 6977 }; 6978 DelayedRunner.prototype.isPaused = function () { 6979 return Object.keys(this.pauseDepths).length; 6980 }; 6981 DelayedRunner.prototype.tryDrain = function () { 6982 if (!this.isRunning && !this.isPaused()) { 6983 this.isRunning = true; 6984 while (this.isDirty) { 6985 this.isDirty = false; 6986 this.drained(); // might set isDirty to true again 6987 } 6988 this.isRunning = false; 6989 } 6990 }; 6991 DelayedRunner.prototype.clear = function () { 6992 this.clearTimeout(); 6993 this.isDirty = false; 6994 this.pauseDepths = {}; 6995 }; 6996 DelayedRunner.prototype.clearTimeout = function () { 6997 if (this.timeoutId) { 6998 clearTimeout(this.timeoutId); 6999 this.timeoutId = 0; 7000 } 7001 }; 7002 DelayedRunner.prototype.drained = function () { 7003 if (this.drainedOption) { 7004 this.drainedOption(); 7005 } 7006 }; 7007 return DelayedRunner; 7008 }()); 7009 7010 var TaskRunner = /** @class */ (function () { 7011 function TaskRunner(runTaskOption, drainedOption) { 7012 this.runTaskOption = runTaskOption; 7013 this.drainedOption = drainedOption; 7014 this.queue = []; 7015 this.delayedRunner = new DelayedRunner(this.drain.bind(this)); 7016 } 7017 TaskRunner.prototype.request = function (task, delay) { 7018 this.queue.push(task); 7019 this.delayedRunner.request(delay); 7020 }; 7021 TaskRunner.prototype.pause = function (scope) { 7022 this.delayedRunner.pause(scope); 7023 }; 7024 TaskRunner.prototype.resume = function (scope, force) { 7025 this.delayedRunner.resume(scope, force); 7026 };
7027 TaskRunner.prototype.drain = function () { 7028 var queue = this.queue; 7029 while (queue.length) { 7030 var completedTasks = []; 7031 var task = void 0; 7032 while ((task = queue.shift())) { 7033 this.runTask(task); 7034 completedTasks.push(task); 7035 } 7036 this.drained(completedTasks); 7037 } // keep going, in case new tasks were added in the drained handler 7038 }; 7039 TaskRunner.prototype.runTask = function (task) { 7040 if (this.runTaskOption) { 7041 this.runTaskOption(task); 7042 } 7043 }; 7044 TaskRunner.prototype.drained = function (completedTasks) { 7045 if (this.drainedOption) { 7046 this.drainedOption(completedTasks); 7047 } 7048 }; 7049 return TaskRunner; 7050 }()); 7051 7052 // Computes what the title at the top of the calendarApi should be for this view 7053 function buildTitle(dateProfile, viewOptions, dateEnv) { 7054 var range; 7055 // for views that span a large unit of time, show the proper interval, ignoring stray days before and after 7056 if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) { 7057 range = dateProfile.currentRange; 7058 } 7059 else { // for day units or smaller, use the actual day range 7060 range = dateProfile.activeRange; 7061 } 7062 return dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || buildTitleFormat(dateProfile)), { 7063 isEndExclusive: dateProfile.isRangeAllDay, 7064 defaultSeparator: viewOptions.titleRangeSeparator, 7065 }); 7066 } 7067 // Generates the format string that should be used to generate the title for the current date range. 7068 // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`. 7069 function buildTitleFormat(dateProfile) { 7070 var currentRangeUnit = dateProfile.currentRangeUnit; 7071 if (currentRangeUnit === 'year') { 7072 return { year: 'numeric' }; 7073 } 7074 if (currentRangeUnit === 'month') { 7075 return { year: 'numeric', month: 'long' }; // like "September 2014" 7076 } 7077 var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end); 7078 if (days !== null && days > 1) { 7079 // multi-day range. shorter, like "Sep 9 - 10 2014" 7080 return { year: 'numeric', month: 'short', day: 'numeric' }; 7081 } 7082 // one day. longer, like "September 9 2014" 7083 return { year: 'numeric', month: 'long', day: 'numeric' }; 7084 } 7085 7086 // in future refactor, do the redux-style function(state=initial) for initial-state 7087 // also, whatever is happening in constructor, have it happen in action queue too 7088 var CalendarDataManager = /** @class */ (function () { 7089 function CalendarDataManager(props) { 7090 var _this = this; 7091 this.computeOptionsData = memoize(this._computeOptionsData); 7092 this.computeCurrentViewData = memoize(this._computeCurrentViewData); 7093 this.organizeRawLocales = memoize(organizeRawLocales); 7094 this.buildLocale = memoize(buildLocale); 7095 this.buildPluginHooks = buildBuildPluginHooks(); 7096 this.buildDateEnv = memoize(buildDateEnv); 7097 this.buildTheme = memoize(buildTheme); 7098 this.parseToolbars = memoize(parseToolbars); 7099 this.buildViewSpecs = memoize(buildViewSpecs); 7100 this.buildDateProfileGenerator = memoizeObjArg(buildDateProfileGenerator); 7101 this.buildViewApi = memoize(buildViewApi); 7102 this.buildViewUiProps = memoizeObjArg(buildViewUiProps); 7103 this.buildEventUiBySource = memoize(buildEventUiBySource, isPropsEqual); 7104 this.buildEventUiBases = memoize(buildEventUiBases); 7105 this.parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours); 7106 this.buildTitle = memoize(buildTitle); 7107 this.emitter = new Emitter(); 7108 this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this)); 7109 this.currentCalendarOptionsInput = {}; 7110 this.currentCalendarOptionsRefined = {}; 7111 this.currentViewOptionsInput = {}; 7112 this.currentViewOptionsRefined = {}; 7113 this.currentCalendarOptionsRefiners = {}; 7114 this.getCurrentData = function () { return _this.data; }; 7115 this.dispatch = function (action) { 7116 _this.actionRunner.request(action); // protects against recursive calls to _handleAction 7117 }; 7118 this.props = props; 7119 this.actionRunner.pause(); 7120 var dynamicOptionOverrides = {}; 7121 var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi); 7122 var currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView; 7123 var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides); 7124 // wire things up 7125 // TODO: not DRY 7126 props.calendarApi.currentDataManager = this; 7127 this.emitter.setThisContext(props.calendarApi); 7128 this.emitter.setOptions(currentViewData.options); 7129 var currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv); 7130 var dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 7131 if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) { 7132 currentDate = dateProfile.currentRange.start; 7133 } 7134 var calendarContext = { 7135 dateEnv: optionsData.dateEnv, 7136 options: optionsData.calendarOptions, 7137 pluginHooks: optionsData.pluginHooks, 7138 calendarApi: props.calendarApi, 7139 dispatch: this.dispatch, 7140 emitter: this.emitter, 7141 getCurrentData: this.getCurrentData, 7142 }; 7143 // needs to be after setThisContext 7144 for (var _i = 0, _a = optionsData.pluginHooks.contextInit; _i < _a.length; _i++) { 7145 var callback = _a[_i]; 7146 callback(calendarContext); 7147 } 7148 // NOT DRY 7149 var eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext); 7150 var initialState = { 7151 dynamicOptionOverrides: dynamicOptionOverrides, 7152 currentViewType: currentViewType, 7153 currentDate: currentDate, 7154 dateProfile: dateProfile, 7155 businessHours: this.parseContextBusinessHours(calendarContext), 7156 eventSources: eventSources, 7157 eventUiBases: {}, 7158 eventStore: createEmptyEventStore(), 7159 renderableEventStore: createEmptyEventStore(), 7160 dateSelection: null, 7161 eventSelection: '', 7162 eventDrag: null, 7163 eventResize: null, 7164 selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig, 7165 }; 7166 var contextAndState = __assign(__assign({}, calendarContext), initialState); 7167 for (var _b = 0, _c = optionsData.pluginHooks.reducers; _b < _c.length; _b++) { 7168 var reducer = _c[_b]; 7169 __assign(initialState, reducer(null, null, contextAndState)); 7170 } 7171 if (computeIsLoading(initialState, calendarContext)) { 7172 this.emitter.trigger('loading', true); // NOT DRY 7173 } 7174 this.state = initialState; 7175 this.updateData(); 7176 this.actionRunner.resume(); 7177 } 7178 CalendarDataManager.prototype.resetOptions = function (optionOverrides, append) { 7179 var props = this.props; 7180 props.optionOverrides = append 7181 ? __assign(__assign({}, props.optionOverrides), optionOverrides) : optionOverrides; 7182 this.actionRunner.request({ 7183 type: 'NOTHING', 7184 }); 7185 }; 7186 CalendarDataManager.prototype._handleAction = function (action) { 7187 var _a = this, props = _a.props, state = _a.state, emitter = _a.emitter; 7188 var dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action); 7189 var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi); 7190 var currentViewType = reduceViewType(state.currentViewType, action); 7191 var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides); 7192 // wire things up 7193 // TODO: not DRY 7194 props.calendarApi.currentDataManager = this; 7195 emitter.setThisContext(props.calendarApi); 7196 emitter.setOptions(currentViewData.options); 7197 var calendarContext = { 7198 dateEnv: optionsData.dateEnv, 7199 options: optionsData.calendarOptions, 7200 pluginHooks: optionsData.pluginHooks, 7201 calendarApi: props.calendarApi, 7202 dispatch: this.dispatch, 7203 emitter: emitter, 7204 getCurrentData: this.getCurrentData, 7205 }; 7206 var currentDate = state.currentDate, dateProfile = state.dateProfile; 7207 if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack 7208 dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 7209 } 7210 currentDate = reduceCurrentDate(currentDate, action); 7211 dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator); 7212 if (action.type === 'PREV' || // TODO: move this logic into DateProfileGenerator 7213 action.type === 'NEXT' || // " 7214 !rangeContainsMarker(dateProfile.currentRange, currentDate)) { 7215 currentDate = dateProfile.currentRange.start; 7216 } 7217 var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext); 7218 var eventStore = reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendarContext); 7219 var isEventsLoading = computeEventSourcesLoading(eventSources);
7219 // BAD. also called in this func in computeIsLoading 7220 var renderableEventStore = (isEventsLoading && !currentViewData.options.progressiveEventRendering) ? 7221 (state.renderableEventStore || eventStore) : // try from previous state 7222 eventStore; 7223 var _b = this.buildViewUiProps(calendarContext), eventUiSingleBase = _b.eventUiSingleBase, selectionConfig = _b.selectionConfig; // will memoize obj 7224 var eventUiBySource = this.buildEventUiBySource(eventSources); 7225 var eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource); 7226 var newState = { 7227 dynamicOptionOverrides: dynamicOptionOverrides, 7228 currentViewType: currentViewType, 7229 currentDate: currentDate, 7230 dateProfile: dateProfile, 7231 eventSources: eventSources, 7232 eventStore: eventStore, 7233 renderableEventStore: renderableEventStore, 7234 selectionConfig: selectionConfig, 7235 eventUiBases: eventUiBases, 7236 businessHours: this.parseContextBusinessHours(calendarContext), 7237 dateSelection: reduceDateSelection(state.dateSelection, action), 7238 eventSelection: reduceSelectedEvent(state.eventSelection, action), 7239 eventDrag: reduceEventDrag(state.eventDrag, action), 7240 eventResize: reduceEventResize(state.eventResize, action), 7241 }; 7242 var contextAndState = __assign(__assign({}, calendarContext), newState); 7243 for (var _i = 0, _c = optionsData.pluginHooks.reducers; _i < _c.length; _i++) { 7244 var reducer = _c[_i]; 7245 __assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value 7246 } 7247 var wasLoading = computeIsLoading(state, calendarContext); 7248 var isLoading = computeIsLoading(newState, calendarContext); 7249 // TODO: use propSetHandlers in plugin system 7250 if (!wasLoading && isLoading) { 7251 emitter.trigger('loading', true); 7252 } 7253 else if (wasLoading && !isLoading) { 7254 emitter.trigger('loading', false); 7255 } 7256 this.state = newState; 7257 if (props.onAction) { 7258 props.onAction(action); 7259 } 7260 }; 7261 CalendarDataManager.prototype.updateData = function () { 7262 var _a = this, props = _a.props, state = _a.state; 7263 var oldData = this.data; 7264 var optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi); 7265 var currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides); 7266 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); 7267 var changeHandlers = optionsData.pluginHooks.optionChangeHandlers; 7268 var oldCalendarOptions = oldData && oldData.calendarOptions; 7269 var newCalendarOptions = optionsData.calendarOptions; 7270 if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) { 7271 if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) { 7272 // hack 7273 state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data); 7274 state.eventStore = data.eventStore = rezoneEventStoreDates(data.eventStore, oldData.dateEnv, data.dateEnv); 7275 } 7276 for (var optionName in changeHandlers) { 7277 if (oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) { 7278 changeHandlers[optionName](newCalendarOptions[optionName], data); 7279 } 7280 } 7281 } 7282 if (props.onData) { 7283 props.onData(data); 7284 } 7285 }; 7286 CalendarDataManager.prototype._computeOptionsData = function (optionOverrides, dynamicOptionOverrides, calendarApi) { 7287 // TODO: blacklist options that are handled by optionChangeHandlers 7288 var _a = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, pluginHooks = _a.pluginHooks, localeDefaults = _a.localeDefaults, availableLocaleData = _a.availableLocaleData, extra = _a.extra; 7289 warnUnknownOptions(extra); 7290 var dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator); 7291 var viewSpecs = this.buildViewSpecs(pluginHooks.views, optionOverrides, dynamicOptionOverrides, localeDefaults); 7292 var theme = this.buildTheme(refinedOptions, pluginHooks); 7293 var toolbarConfig = this.parseToolbars(refinedOptions, optionOverrides, theme, viewSpecs, calendarApi); 7294 return { 7295 calendarOptions: refinedOptions, 7296 pluginHooks: pluginHooks, 7297 dateEnv: dateEnv, 7298 viewSpecs: viewSpecs, 7299 theme: theme, 7300 toolbarConfig: toolbarConfig, 7301 localeDefaults: localeDefaults, 7302 availableRawLocales: availableLocaleData.map, 7303 }; 7304 }; 7305 // always called from behind a memoizer 7306 CalendarDataManager.prototype.processRawCalendarOptions = function (optionOverrides, dynamicOptionOverrides) { 7307 var _a = mergeRawOptions([ 7308 BASE_OPTION_DEFAULTS, 7309 optionOverrides, 7310 dynamicOptionOverrides, 7311 ]), locales = _a.locales, locale = _a.locale; 7312 var availableLocaleData = this.organizeRawLocales(locales); 7313 var availableRawLocales = availableLocaleData.map; 7314 var localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options; 7315 var pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins); 7316 var refiners = this.currentCalendarOptionsRefiners = __assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners); 7317 var extra = {}; 7318 var raw = mergeRawOptions([ 7319 BASE_OPTION_DEFAULTS, 7320 localeDefaults, 7321 optionOverrides, 7322 dynamicOptionOverrides, 7323 ]);
7324 var refined = {}; 7325 var currentRaw = this.currentCalendarOptionsInput; 7326 var currentRefined = this.currentCalendarOptionsRefined; 7327 var anyChanges = false; 7328 for (var optionName in raw) { 7329 if (optionName !== 'plugins') { // because plugins is special-cased 7330 if (raw[optionName] === currentRaw[optionName] || 7331 (COMPLEX_OPTION_COMPARATORS[optionName] && 7332 (optionName in currentRaw) && 7333 COMPLEX_OPTION_COMPARATORS[optionName](currentRaw[optionName], raw[optionName]))) { 7334 refined[optionName] = currentRefined[optionName]; 7335 } 7336 else if (refiners[optionName]) { 7337 refined[optionName] = refiners[optionName](raw[optionName]); 7338 anyChanges = true; 7339 } 7340 else { 7341 extra[optionName] = currentRaw[optionName]; 7342 } 7343 } 7344 } 7345 if (anyChanges) { 7346 this.currentCalendarOptionsInput = raw; 7347 this.currentCalendarOptionsRefined = refined; 7348 } 7349 return { 7350 rawOptions: this.currentCalendarOptionsInput, 7351 refinedOptions: this.currentCalendarOptionsRefined, 7352 pluginHooks: pluginHooks, 7353 availableLocaleData: availableLocaleData, 7354 localeDefaults: localeDefaults, 7355 extra: extra, 7356 }; 7357 }; 7358 CalendarDataManager.prototype._computeCurrentViewData = function (viewType, optionsData, optionOverrides, dynamicOptionOverrides) { 7359 var viewSpec = optionsData.viewSpecs[viewType]; 7360 if (!viewSpec) { 7361 throw new Error("viewType \"" + viewType + "\" is not available. Please make sure you've loaded all neccessary plugins"); 7362 } 7363 var _a = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, extra = _a.extra; 7364 warnUnknownOptions(extra); 7365 var dateProfileGenerator = this.buildDateProfileGenerator({ 7366 dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass, 7367 duration: viewSpec.duration, 7368 durationUnit: viewSpec.durationUnit, 7369 usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime, 7370 dateEnv: optionsData.dateEnv, 7371 calendarApi: this.props.calendarApi, 7372 slotMinTime: refinedOptions.slotMinTime, 7373 slotMaxTime: refinedOptions.slotMaxTime, 7374 showNonCurrentDates: refinedOptions.showNonCurrentDates, 7375 dayCount: refinedOptions.dayCount, 7376 dateAlignment: refinedOptions.dateAlignment, 7377 dateIncrement: refinedOptions.dateIncrement, 7378 hiddenDays: refinedOptions.hiddenDays, 7379 weekends: refinedOptions.weekends, 7380 nowInput: refinedOptions.now, 7381 validRangeInput: refinedOptions.validRange, 7382 visibleRangeInput: refinedOptions.visibleRange, 7383 monthMode: refinedOptions.monthMode, 7384 fixedWeekCount: refinedOptions.fixedWeekCount, 7385 }); 7386 var viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv); 7387 return { viewSpec: viewSpec, options: refinedOptions, dateProfileGenerator: dateProfileGenerator, viewApi: viewApi }; 7388 }; 7389 CalendarDataManager.prototype.processRawViewOptions = function (viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) { 7390 var raw = mergeRawOptions([ 7391 BASE_OPTION_DEFAULTS, 7392 viewSpec.optionDefaults, 7393 localeDefaults, 7394 optionOverrides, 7395 viewSpec.optionOverrides, 7396 dynamicOptionOverrides, 7397 ]); 7398 var refiners = __assign(__assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), VIEW_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
7399 var refined = {}; 7400 var currentRaw = this.currentViewOptionsInput; 7401 var currentRefined = this.currentViewOptionsRefined; 7402 var anyChanges = false; 7403 var extra = {}; 7404 for (var optionName in raw) { 7405 if (raw[optionName] === currentRaw[optionName] || 7406 (COMPLEX_OPTION_COMPARATORS[optionName] && 7407 COMPLEX_OPTION_COMPARATORS[optionName](raw[optionName], currentRaw[optionName]))) { 7408 refined[optionName] = currentRefined[optionName]; 7409 } 7410 else { 7411 if (raw[optionName] === this.currentCalendarOptionsInput[optionName] || 7412 (COMPLEX_OPTION_COMPARATORS[optionName] && 7413 COMPLEX_OPTION_COMPARATORS[optionName](raw[optionName], this.currentCalendarOptionsInput[optionName]))) { 7414 if (optionName in this.currentCalendarOptionsRefined) { // might be an "extra" prop 7415 refined[optionName] = this.currentCalendarOptionsRefined[optionName]; 7416 } 7417 } 7418 else if (refiners[optionName]) { 7419 refined[optionName] = refiners[optionName](raw[optionName]); 7420 } 7421 else { 7422 extra[optionName] = raw[optionName]; 7423 } 7424 anyChanges = true; 7425 } 7426 } 7427 if (anyChanges) { 7428 this.currentViewOptionsInput = raw; 7429 this.currentViewOptionsRefined = refined; 7430 } 7431 return { 7432 rawOptions: this.currentViewOptionsInput, 7433 refinedOptions: this.currentViewOptionsRefined, 7434 extra: extra, 7435 }; 7436 }; 7437 return CalendarDataManager; 7438 }()); 7439 function buildDateEnv(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) { 7440 var locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map); 7441 return new DateEnv({ 7442 calendarSystem: 'gregory', 7443 timeZone: timeZone, 7444 namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl, 7445 locale: locale, 7446 weekNumberCalculation: weekNumberCalculation, 7447 firstDay: firstDay, 7448 weekText: weekText, 7449 cmdFormatter: pluginHooks.cmdFormatter, 7450 defaultSeparator: defaultSeparator, 7451 }); 7452 } 7453 function buildTheme(options, pluginHooks) { 7454 var ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme; 7455 return new ThemeClass(options); 7456 } 7457 function buildDateProfileGenerator(props) { 7458 var DateProfileGeneratorClass = props.dateProfileGeneratorClass || DateProfileGenerator; 7459 return new DateProfileGeneratorClass(props); 7460 } 7461 function buildViewApi(type, getCurrentData, dateEnv) { 7462 return new ViewApi(type, getCurrentData, dateEnv); 7463 } 7464 function buildEventUiBySource(eventSources) { 7465 return mapHash(eventSources, function (eventSource) { return eventSource.ui; }); 7466 } 7467 function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) { 7468 var eventUiBases = { '': eventUiSingleBase }; 7469 for (var defId in eventDefs) { 7470 var def = eventDefs[defId]; 7471 if (def.sourceId && eventUiBySource[def.sourceId]) { 7472 eventUiBases[defId] = eventUiBySource[def.sourceId]; 7473 } 7474 } 7475 return eventUiBases; 7476 } 7477 function buildViewUiProps(calendarContext) { 7478 var options = calendarContext.options; 7479 return { 7480 eventUiSingleBase: createEventUi({ 7481 display: options.eventDisplay, 7482 editable: options.editable, 7483 startEditable: options.eventStartEditable, 7484 durationEditable: options.eventDurationEditable, 7485 constraint: options.eventConstraint, 7486 overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined, 7487 allow: options.eventAllow,
7488 backgroundColor: options.eventBackgroundColor, 7489 borderColor: options.eventBorderColor, 7490 textColor: options.eventTextColor, 7491 color: options.eventColor, 7492 // classNames: options.eventClassNames // render hook will handle this 7493 }, calendarContext), 7494 selectionConfig: createEventUi({ 7495 constraint: options.selectConstraint, 7496 overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined, 7497 allow: options.selectAllow, 7498 }, calendarContext), 7499 }; 7500 } 7501 function computeIsLoading(state, context) { 7502 for (var _i = 0, _a = context.pluginHooks.isLoadingFuncs; _i < _a.length; _i++) { 7503 var isLoadingFunc = _a[_i]; 7504 if (isLoadingFunc(state)) { 7505 return true; 7506 } 7507 } 7508 return false; 7509 } 7510 function parseContextBusinessHours(calendarContext) { 7511 return parseBusinessHours(calendarContext.options.businessHours, calendarContext); 7512 } 7513 function warnUnknownOptions(options, viewName) { 7514 for (var optionName in options) { 7515 console.warn("Unknown option '" + optionName + "'" + 7516 (viewName ? " for view '" + viewName + "'" : '')); 7517 } 7518 } 7519 7520 // TODO: move this to react plugin? 7521 var CalendarDataProvider = /** @class */ (function (_super) { 7522 __extends(CalendarDataProvider, _super); 7523 function CalendarDataProvider(props) { 7524 var _this = _super.call(this, props) || this; 7525 _this.handleData = function (data) { 7526 if (!_this.dataManager) { // still within initial run, before assignment in constructor 7527 // eslint-disable-next-line react/no-direct-mutation-state 7528 _this.state = data; // can't use setState yet 7529 } 7530 else { 7531 _this.setState(data); 7532 } 7533 }; 7534 _this.dataManager = new CalendarDataManager({ 7535 optionOverrides: props.optionOverrides, 7536 calendarApi: props.calendarApi, 7537 onData: _this.handleData, 7538 }); 7539 return _this; 7540 } 7541 CalendarDataProvider.prototype.render = function () { 7542 return this.props.children(this.state); 7543 }; 7544 CalendarDataProvider.prototype.componentDidUpdate = function (prevProps) { 7545 var newOptionOverrides = this.props.optionOverrides; 7546 if (newOptionOverrides !== prevProps.optionOverrides) { // prevent recursive handleData 7547 this.dataManager.resetOptions(newOptionOverrides); 7548 } 7549 }; 7550 return CalendarDataProvider; 7551 }(Component)); 7552 7553 // HELPERS 7554 /* 7555 if nextDayThreshold is specified, slicing is done in an all-day fashion. 7556 you can get nextDayThreshold from context.nextDayThreshold 7557 */ 7558 function sliceEvents(props, allDay) { 7559 return sliceEventStore(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg; 7560 } 7561 7562 var NamedTimeZoneImpl = /** @class */ (function () { 7563 function NamedTimeZoneImpl(timeZoneName) { 7564 this.timeZoneName = timeZoneName; 7565 } 7566 return NamedTimeZoneImpl; 7567 }()); 7568 7569 var SegHierarchy = /** @class */ (function () { 7570 function SegHierarchy() { 7571 // settings 7572 this.strictOrder = false; 7573 this.allowReslicing = false; 7574 this.maxCoord = -1; // -1 means no max 7575 this.maxStackCnt = -1; // -1 means no max 7576 this.levelCoords = []; // ordered 7577 this.entriesByLevel = []; // parallel with levelCoords 7578 this.stackCnts = {}; // TODO: use better technique!? 7579 } 7580 SegHierarchy.prototype.addSegs = function (inputs) { 7581 var hiddenEntries = []; 7582 for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) { 7583 var input = inputs_1[_i]; 7584 this.insertEntry(input, hiddenEntries); 7585 } 7586 return hiddenEntries; 7587 }; 7588 SegHierarchy.prototype.insertEntry = function (entry, hiddenEntries) { 7589 var insertion = this.findInsertion(entry); 7590 if (this.isInsertionValid(insertion, entry)) { 7591 this.insertEntryAt(entry, insertion); 7592 return 1; 7593 } 7594 return this.handleInvalidInsertion(insertion, entry, hiddenEntries); 7595 }; 7596 SegHierarchy.prototype.isInsertionValid = function (insertion, entry) { 7597 return (this.maxCoord === -1 || insertion.levelCoord + entry.thickness <= this.maxCoord) && 7598 (this.maxStackCnt === -1 || insertion.stackCnt < this.maxStackCnt); 7599 }; 7600 // returns number of new entries inserted 7601 SegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) {
7602 if (this.allowReslicing && insertion.touchingEntry) { 7603 return this.splitEntry(entry, insertion.touchingEntry, hiddenEntries); 7604 } 7605 hiddenEntries.push(entry); 7606 return 0; 7607 }; 7608 SegHierarchy.prototype.splitEntry = function (entry, barrier, hiddenEntries) { 7609 var partCnt = 0; 7610 var splitHiddenEntries = []; 7611 var entrySpan = entry.span; 7612 var barrierSpan = barrier.span; 7613 if (entrySpan.start < barrierSpan.start) { 7614 partCnt += this.insertEntry({ 7615 index: entry.index, 7616 thickness: entry.thickness, 7617 span: { start: entrySpan.start, end: barrierSpan.start }, 7618 }, splitHiddenEntries); 7619 } 7620 if (entrySpan.end > barrierSpan.end) { 7621 partCnt += this.insertEntry({ 7622 index: entry.index, 7623 thickness: entry.thickness, 7624 span: { start: barrierSpan.end, end: entrySpan.end }, 7625 }, splitHiddenEntries); 7626 } 7627 if (partCnt) { 7628 hiddenEntries.push.apply(hiddenEntries, __spreadArray([{ 7629 index: entry.index, 7630 thickness: entry.thickness, 7631 span: intersectSpans(barrierSpan, entrySpan), // guaranteed to intersect 7632 }], splitHiddenEntries)); 7633 return partCnt; 7634 } 7635 hiddenEntries.push(entry); 7636 return 0; 7637 }; 7638 SegHierarchy.prototype.insertEntryAt = function (entry, insertion) { 7639 var _a = this, entriesByLevel = _a.entriesByLevel, levelCoords = _a.levelCoords; 7640 if (insertion.lateral === -1) { 7641 // create a new level 7642 insertAt(levelCoords, insertion.level, insertion.levelCoord); 7643 insertAt(entriesByLevel, insertion.level, [entry]); 7644 } 7645 else { 7646 // insert into existing level 7647 insertAt(entriesByLevel[insertion.level], insertion.lateral, entry); 7648 } 7649 this.stackCnts[buildEntryKey(entry)] = insertion.stackCnt; 7650 }; 7651 SegHierarchy.prototype.findInsertion = function (newEntry) { 7652 var _a = this, levelCoords = _a.levelCoords, entriesByLevel = _a.entriesByLevel, strictOrder = _a.strictOrder, stackCnts = _a.stackCnts; 7653 var levelCnt = levelCoords.length; 7654 var candidateCoord = 0; 7655 var touchingLevel = -1; 7656 var touchingLateral = -1; 7657 var touchingEntry = null; 7658 var stackCnt = 0; 7659 for (var trackingLevel = 0; trackingLevel < levelCnt; trackingLevel += 1) { 7660 var trackingCoord = levelCoords[trackingLevel]; 7661 // if the current level is past the placed entry, we have found a good empty space and can stop. 7662 // if strictOrder, keep finding more lateral intersections. 7663 if (!strictOrder && trackingCoord >= candidateCoord + newEntry.thickness) { 7664 break; 7665 } 7666 var trackingEntries = entriesByLevel[trackingLevel]; 7667 var trackingEntry = void 0; 7668 var searchRes = binarySearch(trackingEntries, newEntry.span.start, getEntrySpanEnd); // find first entry after newEntry's end 7669 var lateralIndex = searchRes[0] + searchRes[1]; // if exact match (which doesn't collide), go to next one 7670 while ( // loop through entries that horizontally intersect 7671 (trackingEntry = trackingEntries[lateralIndex]) && // but not past the whole entry list 7672 trackingEntry.span.start < newEntry.span.end // and not entirely past newEntry 7673 ) { 7674 var trackingEntryBottom = trackingCoord + trackingEntry.thickness; 7675 // intersects into the top of the candidate? 7676 if (trackingEntryBottom > candidateCoord) { 7677 candidateCoord = trackingEntryBottom; 7678 touchingEntry = trackingEntry; 7679 touchingLevel = trackingLevel; 7680 touchingLateral = lateralIndex; 7681 }
7682 // butts up against top of candidate? (will happen if just intersected as well) 7683 if (trackingEntryBottom === candidateCoord) { 7684 // accumulate the highest possible stackCnt of the trackingEntries that butt up 7685 stackCnt = Math.max(stackCnt, stackCnts[buildEntryKey(trackingEntry)] + 1); 7686 } 7687 lateralIndex += 1; 7688 } 7689 } 7690 // the destination level will be after touchingEntry's level. find it 7691 var destLevel = 0; 7692 if (touchingEntry) { 7693 destLevel = touchingLevel + 1; 7694 while (destLevel < levelCnt && levelCoords[destLevel] < candidateCoord) { 7695 destLevel += 1; 7696 } 7697 } 7698 // if adding to an existing level, find where to insert 7699 var destLateral = -1; 7700 if (destLevel < levelCnt && levelCoords[destLevel] === candidateCoord) { 7701 destLateral = binarySearch(entriesByLevel[destLevel], newEntry.span.end, getEntrySpanEnd)[0]; 7702 } 7703 return { 7704 touchingLevel: touchingLevel, 7705 touchingLateral: touchingLateral, 7706 touchingEntry: touchingEntry, 7707 stackCnt: stackCnt, 7708 levelCoord: candidateCoord, 7709 level: destLevel, 7710 lateral: destLateral, 7711 }; 7712 }; 7713 // sorted by levelCoord (lowest to highest) 7714 SegHierarchy.prototype.toRects = function () { 7715 var _a = this, entriesByLevel = _a.entriesByLevel, levelCoords = _a.levelCoords; 7716 var levelCnt = entriesByLevel.length; 7717 var rects = []; 7718 for (var level = 0; level < levelCnt; level += 1) { 7719 var entries = entriesByLevel[level]; 7720 var levelCoord = levelCoords[level]; 7721 for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { 7722 var entry = entries_1[_i]; 7723 rects.push(__assign(__assign({}, entry), { levelCoord: levelCoord })); 7724 } 7725 } 7726 return rects; 7727 }; 7728 return SegHierarchy; 7729 }()); 7730 function getEntrySpanEnd(entry) { 7731 return entry.span.end; 7732 } 7733 function buildEntryKey(entry) { 7734 return entry.index + ':' + entry.span.start; 7735 } 7736 // returns groups with entries sorted by input order 7737 function groupIntersectingEntries(entries) { 7738 var merges = []; 7739 for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { 7740 var entry = entries_2[_i]; 7741 var filteredMerges = []; 7742 var hungryMerge = { 7743 span: entry.span, 7744 entries: [entry], 7745 }; 7746 for (var _a = 0, merges_1 = merges; _a < merges_1.length; _a++) { 7747 var merge = merges_1[_a]; 7748 if (intersectSpans(merge.span, hungryMerge.span)) { 7749 hungryMerge = { 7750 entries: merge.entries.concat(hungryMerge.entries), 7751 span: joinSpans(merge.span, hungryMerge.span), 7752 }; 7753 } 7754 else { 7755 filteredMerges.push(merge); 7756 } 7757 } 7758 filteredMerges.push(hungryMerge); 7759 merges = filteredMerges; 7760 } 7761 return merges; 7762 } 7763 function joinSpans(span0, span1) { 7764 return { 7765 start: Math.min(span0.start, span1.start), 7766 end: Math.max(span0.end, span1.end), 7767 }; 7768 } 7769 function intersectSpans(span0, span1) { 7770 var start = Math.max(span0.start, span1.start); 7771 var end = Math.min(span0.end, span1.end); 7772 if (start < end) { 7773 return { start: start, end: end }; 7774 } 7775 return null; 7776 } 7777 // general util 7778 // --------------------------------------------------------------------------------------------------------------------- 7779 function insertAt(arr, index, item) { 7780 arr.splice(index, 0, item); 7781 }
7782 function binarySearch(a, searchVal, getItemVal) { 7783 var startIndex = 0; 7784 var endIndex = a.length; // exclusive 7785 if (!endIndex || searchVal < getItemVal(a[startIndex])) { // no items OR before first item 7786 return [0, 0]; 7787 } 7788 if (searchVal > getItemVal(a[endIndex - 1])) { // after last item 7789 return [endIndex, 0]; 7790 } 7791 while (startIndex < endIndex) { 7792 var middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2); 7793 var middleVal = getItemVal(a[middleIndex]); 7794 if (searchVal < middleVal) { 7795 endIndex = middleIndex; 7796 } 7797 else if (searchVal > middleVal) { 7798 startIndex = middleIndex + 1; 7799 } 7800 else { // equal! 7801 return [middleIndex, 1]; 7802 } 7803 } 7804 return [startIndex, 0]; 7805 } 7806 7807 var Interaction = /** @class */ (function () { 7808 function Interaction(settings) { 7809 this.component = settings.component; 7810 this.isHitComboAllowed = settings.isHitComboAllowed || null; 7811 } 7812 Interaction.prototype.destroy = function () { 7813 }; 7814 return Interaction; 7815 }()); 7816 function parseInteractionSettings(component, input) { 7817 return { 7818 component: component, 7819 el: input.el, 7820 useEventCenter: input.useEventCenter != null ? input.useEventCenter : true, 7821 isHitComboAllowed: input.isHitComboAllowed || null, 7822 }; 7823 } 7824 function interactionSettingsToStore(settings) { 7825 var _a; 7826 return _a = {}, 7827 _a[settings.component.uid] = settings, 7828 _a; 7829 } 7830 // global state 7831 var interactionSettingsStore = {}; 7832 7833 /* 7834 An abstraction for a dragging interaction originating on an event. 7835 Does higher-level things than PointerDragger, such as possibly: 7836 - a "mirror" that moves with the pointer 7837 - a minimum number of pixels or other criteria for a true drag to begin 7838 7839 subclasses must emit: 7840 - pointerdown 7841 - dragstart 7842 - dragmove 7843 - pointerup 7844 - dragend 7845 */ 7846 var ElementDragging = /** @class */ (function () { 7847 function ElementDragging(el, selector) { 7848 this.emitter = new Emitter(); 7849 } 7850 ElementDragging.prototype.destroy = function () { 7851 }; 7852 ElementDragging.prototype.setMirrorIsVisible = function (bool) { 7853 // optional if subclass doesn't want to support a mirror 7854 }; 7855 ElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 7856 // optional if subclass doesn't want to support a mirror 7857 }; 7858 ElementDragging.prototype.setAutoScrollEnabled = function (bool) { 7859 // optional 7860 }; 7861 return ElementDragging; 7862 }()); 7863 7864 // TODO: get rid of this in favor of options system, 7865 // tho it's really easy to access this globally rather than pass thru options. 7866 var config = {}; 7867 7868 /* 7869 Information about what will happen when an external element is dragged-and-dropped 7870 onto a calendar. Contains information for creating an event. 7871 */ 7872 var DRAG_META_REFINERS = { 7873 startTime: createDuration, 7874 duration: createDuration, 7875 create: Boolean, 7876 sourceId: String, 7877 }; 7878 function parseDragMeta(raw) { 7879 var _a = refineProps(raw, DRAG_META_REFINERS), refined = _a.refined, extra = _a.extra; 7880 return { 7881 startTime: refined.startTime || null, 7882 duration: refined.duration || null, 7883 create: refined.create != null ? refined.create : true, 7884 sourceId: refined.sourceId, 7885 leftoverProps: extra, 7886 }; 7887 } 7888 7889 var ToolbarSection = /** @class */ (function (_super) { 7890 __extends(ToolbarSection, _super); 7891 function ToolbarSection() { 7892 return _super !== null && _super.apply(this, arguments) || this; 7893 } 7894 ToolbarSection.prototype.render = function () { 7895 var _this = this; 7896 var children = this.props.widgetGroups.map(function (widgetGroup) { return _this.renderWidgetGroup(widgetGroup); }); 7897 return createElement.apply(void 0, __spreadArray(['div', { className: 'fc-toolbar-chunk' }], children)); 7898 }; 7899 ToolbarSection.prototype.renderWidgetGroup = function (widgetGroup) { 7900 var props = this.props; 7901 var theme = this.context.theme; 7902 var children = []; 7903 var isOnlyButtons = true; 7904 for (var _i = 0, widgetGroup_1 = widgetGroup; _i < widgetGroup_1.length; _i++) { 7905 var widget = widgetGroup_1[_i]; 7906 var buttonName = widget.buttonName, buttonClick = widget.buttonClick, buttonText = widget.buttonText, buttonIcon = widget.buttonIcon, buttonHint = widget.buttonHint; 7907 if (buttonName === 'title') { 7908 isOnlyButtons = false; 7909 children.push(createElement("h2", { className: "fc-toolbar-title", id: props.titleId }, props.title)); 7910 } 7911 else { 7912 var isPressed = buttonName === props.activeButton; 7913 var isDisabled = (!props.isTodayEnabled && buttonName === 'today') || 7914 (!props.isPrevEnabled && buttonName === 'prev') || 7915 (!props.isNextEnabled && buttonName === 'next');
7916 var buttonClasses = ["fc-" + buttonName + "-button", theme.getClass('button')]; 7917 if (isPressed) { 7918 buttonClasses.push(theme.getClass('buttonActive')); 7919 } 7920 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 }) : ''))); 7921 } 7922 } 7923 if (children.length > 1) { 7924 var groupClassName = (isOnlyButtons && theme.getClass('buttonGroup')) || ''; 7925 return createElement.apply(void 0, __spreadArray(['div', { className: groupClassName }], children)); 7926 } 7927 return children[0]; 7928 }; 7929 return ToolbarSection; 7930 }(BaseComponent)); 7931 7932 var Toolbar = /** @class */ (function (_super) { 7933 __extends(Toolbar, _super); 7934 function Toolbar() { 7935 return _super !== null && _super.apply(this, arguments) || this; 7936 } 7937 Toolbar.prototype.render = function () { 7938 var _a = this.props, model = _a.model, extraClassName = _a.extraClassName; 7939 var forceLtr = false; 7940 var startContent; 7941 var endContent; 7942 var sectionWidgets = model.sectionWidgets; 7943 var centerContent = sectionWidgets.center; 7944 if (sectionWidgets.left) { 7945 forceLtr = true; 7946 startContent = sectionWidgets.left; 7947 } 7948 else { 7949 startContent = sectionWidgets.start; 7950 } 7951 if (sectionWidgets.right) { 7952 forceLtr = true; 7953 endContent = sectionWidgets.right; 7954 } 7955 else { 7956 endContent = sectionWidgets.end; 7957 } 7958 var classNames = [ 7959 extraClassName || '', 7960 'fc-toolbar', 7961 forceLtr ? 'fc-toolbar-ltr' : '', 7962 ]; 7963 return (createElement("div", { className: classNames.join(' ') }, 7964 this.renderSection('start', startContent || []), 7965 this.renderSection('center', centerContent || []), 7966 this.renderSection('end', endContent || []))); 7967 }; 7968 Toolbar.prototype.renderSection = function (key, widgetGroups) { 7969 var props = this.props; 7970 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 })); 7971 }; 7972 return Toolbar; 7973 }(BaseComponent)); 7974 7975 // TODO: do function component? 7976 var ViewContainer = /** @class */ (function (_super) { 7977 __extends(ViewContainer, _super); 7978 function ViewContainer() { 7979 var _this = _super !== null && _super.apply(this, arguments) || this; 7980 _this.state = { 7981 availableWidth: null, 7982 }; 7983 _this.handleEl = function (el) { 7984 _this.el = el; 7985 setRef(_this.props.elRef, el); 7986 _this.updateAvailableWidth(); 7987 }; 7988 _this.handleResize = function () { 7989 _this.updateAvailableWidth(); 7990 }; 7991 return _this; 7992 } 7993 ViewContainer.prototype.render = function () { 7994 var _a = this, props = _a.props, state = _a.state; 7995 var aspectRatio = props.aspectRatio; 7996 var classNames = [ 7997 'fc-view-harness', 7998 (aspectRatio || props.liquid || props.height) 7999 ? 'fc-view-harness-active' // harness controls the height 8000 : 'fc-view-harness-passive', // let the view do the height 8001 ]; 8002 var height = ''; 8003 var paddingBottom = ''; 8004 if (aspectRatio) { 8005 if (state.availableWidth !== null) { 8006 height = state.availableWidth / aspectRatio; 8007 } 8008 else { 8009 // while waiting to know availableWidth, we can't set height to *zero* 8010 // because will cause lots of unnecessary scrollbars within scrollgrid. 8011 // BETTER: don't start rendering ANYTHING yet until we know container width 8012 // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606) 8013 paddingBottom = (1 / aspectRatio) * 100 + "%"; 8014 } 8015 } 8016 else { 8017 height = props.height || ''; 8018 } 8019 return (createElement("div", { "aria-labelledby": props.labeledById, ref: this.handleEl, className: classNames.join(' '), style: { height: height, paddingBottom: paddingBottom } }, props.children)); 8020 }; 8021 ViewContainer.prototype.componentDidMount = function () { 8022 this.context.addResizeHandler(this.handleResize); 8023 }; 8024 ViewContainer.prototype.componentWillUnmount = function () { 8025 this.context.removeResizeHandler(this.handleResize); 8026 }; 8027 ViewContainer.prototype.updateAvailableWidth = function () { 8028 if (this.el && // needed. but why? 8029 this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth 8030 ) { 8031 this.setState({ availableWidth: this.el.offsetWidth }); 8032 } 8033 }; 8034 return ViewContainer; 8035 }(BaseComponent)); 8036 8037 /* 8038 Detects when the user clicks on an event within a DateComponent 8039 */ 8040 var EventClicking = /** @class */ (function (_super) { 8041 __extends(EventClicking, _super);
8042 function EventClicking(settings) { 8043 var _this = _super.call(this, settings) || this; 8044 _this.handleSegClick = function (ev, segEl) { 8045 var component = _this.component; 8046 var context = component.context; 8047 var seg = getElSeg(segEl); 8048 if (seg && // might be the <div> surrounding the more link 8049 component.isValidSegDownEl(ev.target)) { 8050 // our way to simulate a link click for elements that can't be <a> tags 8051 // grab before trigger fired in case trigger trashes DOM thru rerendering 8052 var hasUrlContainer = elementClosest(ev.target, '.fc-event-forced-url'); 8053 var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : ''; 8054 context.emitter.trigger('eventClick', { 8055 el: segEl, 8056 event: new EventApi(component.context, seg.eventRange.def, seg.eventRange.instance), 8057 jsEvent: ev, 8058 view: context.viewApi, 8059 }); 8060 if (url && !ev.defaultPrevented) { 8061 window.location.href = url; 8062 } 8063 } 8064 }; 8065 _this.destroy = listenBySelector(settings.el, 'click', '.fc-event', // on both fg and bg events 8066 _this.handleSegClick); 8067 return _this; 8068 } 8069 return EventClicking; 8070 }(Interaction)); 8071 8072 /* 8073 Triggers events and adds/removes core classNames when the user's pointer 8074 enters/leaves event-elements of a component. 8075 */ 8076 var EventHovering = /** @class */ (function (_super) { 8077 __extends(EventHovering, _super); 8078 function EventHovering(settings) { 8079 var _this = _super.call(this, settings) || this; 8080 // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it 8081 _this.handleEventElRemove = function (el) { 8082 if (el === _this.currentSegEl) { 8083 _this.handleSegLeave(null, _this.currentSegEl); 8084 } 8085 }; 8086 _this.handleSegEnter = function (ev, segEl) { 8087 if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper 8088 _this.currentSegEl = segEl; 8089 _this.triggerEvent('eventMouseEnter', ev, segEl); 8090 } 8091 }; 8092 _this.handleSegLeave = function (ev, segEl) { 8093 if (_this.currentSegEl) { 8094 _this.currentSegEl = null; 8095 _this.triggerEvent('eventMouseLeave', ev, segEl); 8096 } 8097 }; 8098 _this.removeHoverListeners = listenToHoverBySelector(settings.el, '.fc-event', // on both fg and bg events 8099 _this.handleSegEnter, _this.handleSegLeave); 8100 return _this; 8101 } 8102 EventHovering.prototype.destroy = function () { 8103 this.removeHoverListeners(); 8104 }; 8105 EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) { 8106 var component = this.component; 8107 var context = component.context; 8108 var seg = getElSeg(segEl); 8109 if (!ev || component.isValidSegDownEl(ev.target)) { 8110 context.emitter.trigger(publicEvName, { 8111 el: segEl, 8112 event: new EventApi(context, seg.eventRange.def, seg.eventRange.instance), 8113 jsEvent: ev, 8114 view: context.viewApi, 8115 }); 8116 } 8117 }; 8118 return EventHovering; 8119 }(Interaction)); 8120 8121 var CalendarContent = /** @class */ (function (_super) { 8122 __extends(CalendarContent, _super); 8123 function CalendarContent() { 8124 var _this = _super !== null && _super.apply(this, arguments) || this; 8125 _this.buildViewContext = memoize(buildViewContext); 8126 _this.buildViewPropTransformers = memoize(buildViewPropTransformers); 8127 _this.buildToolbarProps = memoize(buildToolbarProps); 8128 _this.headerRef = createRef(); 8129 _this.footerRef = createRef(); 8130 _this.interactionsStore = {}; 8131 // eslint-disable-next-line 8132 _this.state = { 8133 viewLabelId: getUniqueDomId(), 8134 }; 8135 // Component Registration 8136 // ----------------------------------------------------------------------------------------------------------------- 8137 _this.registerInteractiveComponent = function (component, settingsInput) { 8138 var settings = parseInteractionSettings(component, settingsInput); 8139 var DEFAULT_INTERACTIONS = [ 8140 EventClicking, 8141 EventHovering, 8142 ]; 8143 var interactionClasses = DEFAULT_INTERACTIONS.concat(_this.props.pluginHooks.componentInteractions); 8144 var interactions = interactionClasses.map(function (TheInteractionClass) { return new TheInteractionClass(settings); }); 8145 _this.interactionsStore[component.uid] = interactions; 8146 interactionSettingsStore[component.uid] = settings; 8147 }; 8148 _this.unregisterInteractiveComponent = function (component) { 8149 var listeners = _this.interactionsStore[component.uid]; 8150 if (listeners) { 8151 for (var _i = 0, listeners_1 = listeners; _i < listeners_1.length; _i++) { 8152 var listener = listeners_1[_i]; 8153 listener.destroy(); 8154 } 8155 delete _this.interactionsStore[component.uid]; 8156 } 8157 delete interactionSettingsStore[component.uid]; 8158 }; 8159 // Resizing 8160 // ----------------------------------------------------------------------------------------------------------------- 8161 _this.resizeRunner = new DelayedRunner(function () { 8162 _this.props.emitter.trigger('_resize', true); // should window resizes be considered "forced" ? 8163 _this.props.emitter.trigger('windowResize', { view: _this.props.viewApi }); 8164 }); 8165 _this.handleWindowResize = function (ev) { 8166 var options = _this.props.options; 8167 if (options.handleWindowResize && 8168 ev.target === window // avoid jqui events 8169 ) { 8170 _this.resizeRunner.request(options.windowResizeDelay); 8171 } 8172 }; 8173 return _this; 8174 } 8175 /* 8176 renders INSIDE of an outer div 8177 */ 8178 CalendarContent.prototype.render = function () { 8179 var props = this.props; 8180 var toolbarConfig = props.toolbarConfig, options = props.options; 8181 var toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, getNow(props.options.now, props.dateEnv), // TODO: use NowTimer???? 8182 props.viewTitle); 8183 var viewVGrow = false; 8184 var viewHeight = ''; 8185 var viewAspectRatio; 8186 if (props.isHeightAuto || props.forPrint) { 8187 viewHeight = ''; 8188 } 8189 else if (options.height != null) { 8190 viewVGrow = true; 8191 } 8192 else if (options.contentHeight != null) { 8193 viewHeight = options.contentHeight; 8194 } 8195 else { 8196 viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall 8197 } 8198 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); 8199 var viewLabelId = (toolbarConfig.header && toolbarConfig.header.hasTitle) 8200 ? this.state.viewLabelId 8201 : ''; 8202 return (createElement(ViewContextType.Provider, { value: viewContext }, 8203 toolbarConfig.header && (createElement(Toolbar, __assign({ ref: this.headerRef, extraClassName: "fc-header-toolbar", model: toolbarConfig.header, titleId: viewLabelId }, toolbarProps))), 8204 createElement(ViewContainer, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, labeledById: viewLabelId }, 8205 this.renderView(props), 8206 this.buildAppendContent()), 8207 toolbarConfig.footer && (createElement(Toolbar, __assign({ ref: this.footerRef, extraClassName: "fc-footer-toolbar", model: toolbarConfig.footer, titleId: "" }, toolbarProps))))); 8208 }; 8209 CalendarContent.prototype.componentDidMount = function () { 8210 var props = this.props; 8211 this.calendarInteractions = props.pluginHooks.calendarInteractions 8212 .map(function (CalendarInteractionClass) { return new CalendarInteractionClass(props); }); 8213 window.addEventListener('resize', this.handleWindowResize); 8214 var propSetHandlers = props.pluginHooks.propSetHandlers; 8215 for (var propName in propSetHandlers) { 8216 propSetHandlers[propName](props[propName], props); 8217 } 8218 }; 8219 CalendarContent.prototype.componentDidUpdate = function (prevProps) { 8220 var props = this.props; 8221 var propSetHandlers = props.pluginHooks.propSetHandlers; 8222 for (var propName in propSetHandlers) { 8223 if (props[propName] !== prevProps[propName]) { 8224 propSetHandlers[propName](props[propName], props); 8225 } 8226 } 8227 }; 8228 CalendarContent.prototype.componentWillUnmount = function () { 8229 window.removeEventListener('resize', this.handleWindowResize); 8230 this.resizeRunner.clear(); 8231 for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) { 8232 var interaction = _a[_i]; 8233 interaction.destroy(); 8234 } 8235 this.props.emitter.trigger('_unmount'); 8236 }; 8237 CalendarContent.prototype.buildAppendContent = function () { 8238 var props = this.props; 8239 var children = props.pluginHooks.viewContainerAppends.map(function (buildAppendContent) { return buildAppendContent(props); }); 8240 return createElement.apply(void 0, __spreadArray([Fragment, {}], children)); 8241 }; 8242 CalendarContent.prototype.renderView = function (props) { 8243 var pluginHooks = props.pluginHooks; 8244 var viewSpec = props.viewSpec; 8245 var viewProps = { 8246 dateProfile: props.dateProfile, 8247 businessHours: props.businessHours, 8248 eventStore: props.renderableEventStore, 8249 eventUiBases: props.eventUiBases, 8250 dateSelection: props.dateSelection, 8251 eventSelection: props.eventSelection, 8252 eventDrag: props.eventDrag, 8253 eventResize: props.eventResize, 8254 isHeightAuto: props.isHeightAuto, 8255 forPrint: props.forPrint, 8256 }; 8257 var transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers); 8258 for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) { 8259 var transformer = transformers_1[_i]; 8260 __assign(viewProps, transformer.transform(viewProps, props)); 8261 } 8262 var ViewComponent = viewSpec.component; 8263 return (createElement(ViewComponent, __assign({}, viewProps))); 8264 }; 8265 return CalendarContent; 8266 }(PureComponent)); 8267 function buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) { 8268 // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid 8269 var todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason 8270 var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false); 8271 var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false); 8272 return { 8273 title: title, 8274 activeButton: viewSpec.type, 8275 navUnit: viewSpec.singleUnit, 8276 isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now), 8277 isPrevEnabled: prevInfo.isValid, 8278 isNextEnabled: nextInfo.isValid, 8279 }; 8280 } 8281 // Plugin 8282 // ----------------------------------------------------------------------------------------------------------------- 8283 function buildViewPropTransformers(theClasses) { 8284 return theClasses.map(function (TheClass) { return new TheClass(); }); 8285 } 8286 8287 var CalendarRoot = /** @class */ (function (_super) { 8288 __extends(CalendarRoot, _super); 8289 function CalendarRoot() { 8290 var _this = _super !== null && _super.apply(this, arguments) || this; 8291 _this.state = { 8292 forPrint: false, 8293 }; 8294 _this.handleBeforePrint = function () { 8295 _this.setState({ forPrint: true });
8296 }; 8297 _this.handleAfterPrint = function () { 8298 _this.setState({ forPrint: false }); 8299 }; 8300 return _this; 8301 } 8302 CalendarRoot.prototype.render = function () { 8303 var props = this.props; 8304 var options = props.options; 8305 var forPrint = this.state.forPrint; 8306 var isHeightAuto = forPrint || options.height === 'auto' || options.contentHeight === 'auto'; 8307 var height = (!isHeightAuto && options.height != null) ? options.height : ''; 8308 var classNames = [ 8309 'fc', 8310 forPrint ? 'fc-media-print' : 'fc-media-screen', 8311 "fc-direction-" + options.direction, 8312 props.theme.getClass('root'), 8313 ]; 8314 if (!getCanVGrowWithinCell()) { 8315 classNames.push('fc-liquid-hack'); 8316 } 8317 return props.children(classNames, height, isHeightAuto, forPrint); 8318 }; 8319 CalendarRoot.prototype.componentDidMount = function () { 8320 var emitter = this.props.emitter; 8321 emitter.on('_beforeprint', this.handleBeforePrint); 8322 emitter.on('_afterprint', this.handleAfterPrint); 8323 }; 8324 CalendarRoot.prototype.componentWillUnmount = function () { 8325 var emitter = this.props.emitter; 8326 emitter.off('_beforeprint', this.handleBeforePrint); 8327 emitter.off('_afterprint', this.handleAfterPrint); 8328 }; 8329 return CalendarRoot; 8330 }(BaseComponent)); 8331 8332 // Computes a default column header formatting string if `colFormat` is not explicitly defined 8333 function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) { 8334 // if more than one week row, or if there are a lot of columns with not much space, 8335 // put just the day numbers will be in each cell 8336 if (!datesRepDistinctDays || dayCnt > 10) { 8337 return createFormatter({ weekday: 'short' }); // "Sat" 8338 } 8339 if (dayCnt > 1) { 8340 return createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }); // "Sat 11/12" 8341 } 8342 return createFormatter({ weekday: 'long' }); // "Saturday" 8343 } 8344 8345 var CLASS_NAME = 'fc-col-header-cell'; // do the cushion too? no 8346 function renderInner$1(hookProps) { 8347 return hookProps.text; 8348 } 8349 8350 var TableDateCell = /** @class */ (function (_super) { 8351 __extends(TableDateCell, _super); 8352 function TableDateCell() { 8353 return _super !== null && _super.apply(this, arguments) || this; 8354 } 8355 TableDateCell.prototype.render = function () { 8356 var _a = this.context, dateEnv = _a.dateEnv, options = _a.options, theme = _a.theme, viewApi = _a.viewApi; 8357 var props = this.props; 8358 var date = props.date, dateProfile = props.dateProfile; 8359 var dayMeta = getDateMeta(date, props.todayRange, null, dateProfile); 8360 var classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme)); 8361 var text = dateEnv.format(date, props.dayHeaderFormat); 8362 // if colCnt is 1, we are already in a day-view and don't need a navlink 8363 var navLinkAttrs = (!dayMeta.isDisabled && props.colCnt > 1) 8364 ? buildNavLinkAttrs(this.context, date) 8365 : {}; 8366 var hookProps = __assign(__assign(__assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraHookProps), { text: text }), dayMeta); 8367 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), 8368 createElement("div", { className: "fc-scrollgrid-sync-inner" }, !dayMeta.isDisabled && (createElement("a", __assign({ ref: innerElRef, className: [ 8369 'fc-col-header-cell-cushion', 8370 props.isSticky ? 'fc-sticky' : '', 8371 ].join(' ') }, navLinkAttrs), innerContent))))); })); 8372 }; 8373 return TableDateCell; 8374 }(BaseComponent)); 8375 8376 var WEEKDAY_FORMAT = createFormatter({ weekday: 'long' }); 8377 var TableDowCell = /** @class */ (function (_super) { 8378 __extends(TableDowCell, _super); 8379 function TableDowCell() { 8380 return _super !== null && _super.apply(this, arguments) || this; 8381 } 8382 TableDowCell.prototype.render = function () { 8383 var props = this.props; 8384 var _a = this.context, dateEnv = _a.dateEnv, theme = _a.theme, viewApi = _a.viewApi, options = _a.options; 8385 var date = addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT 8386 var dateMeta = { 8387 dow: props.dow, 8388 isDisabled: false, 8389 isFuture: false, 8390 isPast: false, 8391 isToday: false, 8392 isOther: false, 8393 }; 8394 var classNames = [CLASS_NAME].concat(getDayClassNames(dateMeta, theme), props.extraClassNames || []); 8395 var text = dateEnv.format(date, props.dayHeaderFormat); 8396 var hookProps = __assign(__assign(__assign(__assign({ // TODO: make this public? 8397 date: date }, dateMeta), { view: viewApi }), props.extraHookProps), { text: text }); 8398 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
8398oncat(customClassNames).join(' '), colSpan: props.colSpan }, props.extraDataAttrs), 8399 createElement("div", { className: "fc-scrollgrid-sync-inner" }, 8400 createElement("a", { "aria-label": dateEnv.format(date, WEEKDAY_FORMAT), className: [ 8401 'fc-col-header-cell-cushion', 8402 props.isSticky ? 'fc-sticky' : '', 8403 ].join(' '), ref: innerElRef }, innerContent)))); })); 8404 }; 8405 return TableDowCell; 8406 }(BaseComponent)); 8407 8408 var NowTimer = /** @class */ (function (_super) { 8409 __extends(NowTimer, _super); 8410 function NowTimer(props, context) { 8411 var _this = _super.call(this, props, context) || this; 8412 _this.initialNowDate = getNow(context.options.now, context.dateEnv); 8413 _this.initialNowQueriedMs = new Date().valueOf(); 8414 _this.state = _this.computeTiming().currentState; 8415 return _this; 8416 } 8417 NowTimer.prototype.render = function () { 8418 var _a = this, props = _a.props, state = _a.state; 8419 return props.children(state.nowDate, state.todayRange); 8420 }; 8421 NowTimer.prototype.componentDidMount = function () { 8422 this.setTimeout(); 8423 }; 8424 NowTimer.prototype.componentDidUpdate = function (prevProps) { 8425 if (prevProps.unit !== this.props.unit) { 8426 this.clearTimeout(); 8427 this.setTimeout(); 8428 } 8429 }; 8430 NowTimer.prototype.componentWillUnmount = function () { 8431 this.clearTimeout(); 8432 }; 8433 NowTimer.prototype.computeTiming = function () { 8434 var _a = this, props = _a.props, context = _a.context; 8435 var unroundedNow = addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs); 8436 var currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit); 8437 var nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit)); 8438 var waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf(); 8439 // there is a max setTimeout ms value (https://stackoverflow.com/a/3468650/96342) 8440 // ensure no longer than a day 8441 waitMs = Math.min(1000 * 60 * 60 * 24, waitMs); 8442 return { 8443 currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) }, 8444 nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) }, 8445 waitMs: waitMs, 8446 }; 8447 }; 8448 NowTimer.prototype.setTimeout = function () { 8449 var _this = this; 8450 var _a = this.computeTiming(), nextState = _a.nextState, waitMs = _a.waitMs; 8451 this.timeoutId = setTimeout(function () { 8452 _this.setState(nextState, function () { 8453 _this.setTimeout(); 8454 }); 8455 }, waitMs); 8456 }; 8457 NowTimer.prototype.clearTimeout = function () { 8458 if (this.timeoutId) { 8459 clearTimeout(this.timeoutId); 8460 } 8461 }; 8462 NowTimer.contextType = ViewContextType; 8463 return NowTimer; 8464 }(Component)); 8465 function buildDayRange(date) { 8466 var start = startOfDay(date); 8467 var end = addDays(start, 1); 8468 return { start: start, end: end }; 8469 } 8470 8471 var DayHeader = /** @class */ (function (_super) { 8472 __extends(DayHeader, _super); 8473 function DayHeader() { 8474 var _this = _super !== null && _super.apply(this, arguments) || this; 8475 _this.createDayHeaderFormatter = memoize(createDayHeaderFormatter); 8476 return _this; 8477 } 8478 DayHeader.prototype.render = function () { 8479 var context = this.context; 8480 var _a = this.props, dates = _a.dates, dateProfile = _a.dateProfile, datesRepDistinctDays = _a.datesRepDistinctDays, renderIntro = _a.renderIntro; 8481 var dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length); 8482 return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement("tr", { role: "row" }, 8483 renderIntro && renderIntro('day'), 8484 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 }))); }))); })); 8485 }; 8486 return DayHeader; 8487 }(BaseComponent)); 8488 function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) { 8489 return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt); 8490 } 8491
8492 var DaySeriesModel = /** @class */ (function () { 8493 function DaySeriesModel(range, dateProfileGenerator) { 8494 var date = range.start; 8495 var end = range.end; 8496 var indices = []; 8497 var dates = []; 8498 var dayIndex = -1; 8499 while (date < end) { // loop each day from start to end 8500 if (dateProfileGenerator.isHiddenDay(date)) { 8501 indices.push(dayIndex + 0.5); // mark that it's between indices 8502 } 8503 else { 8504 dayIndex += 1; 8505 indices.push(dayIndex); 8506 dates.push(date); 8507 } 8508 date = addDays(date, 1); 8509 } 8510 this.dates = dates; 8511 this.indices = indices; 8512 this.cnt = dates.length; 8513 } 8514 DaySeriesModel.prototype.sliceRange = function (range) { 8515 var firstIndex = this.getDateDayIndex(range.start); // inclusive first index 8516 var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index 8517 var clippedFirstIndex = Math.max(0, firstIndex); 8518 var clippedLastIndex = Math.min(this.cnt - 1, lastIndex); 8519 // deal with in-between indices 8520 clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell 8521 clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell 8522 if (clippedFirstIndex <= clippedLastIndex) { 8523 return { 8524 firstIndex: clippedFirstIndex, 8525 lastIndex: clippedLastIndex, 8526 isStart: firstIndex === clippedFirstIndex, 8527 isEnd: lastIndex === clippedLastIndex, 8528 }; 8529 } 8530 return null; 8531 }; 8532 // Given a date, returns its chronolocial cell-index from the first cell of the grid. 8533 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets. 8534 // If before the first offset, returns a negative number. 8535 // If after the last offset, returns an offset past the last cell offset. 8536 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells. 8537 DaySeriesModel.prototype.getDateDayIndex = function (date) { 8538 var indices = this.indices; 8539 var dayOffset = Math.floor(diffDays(this.dates[0], date)); 8540 if (dayOffset < 0) { 8541 return indices[0] - 1; 8542 } 8543 if (dayOffset >= indices.length) { 8544 return indices[indices.length - 1] + 1; 8545 } 8546 return indices[dayOffset]; 8547 };
8548 return DaySeriesModel; 8549 }()); 8550 8551 var DayTableModel = /** @class */ (function () { 8552 function DayTableModel(daySeries, breakOnWeeks) { 8553 var dates = daySeries.dates; 8554 var daysPerRow; 8555 var firstDay; 8556 var rowCnt; 8557 if (breakOnWeeks) { 8558 // count columns until the day-of-week repeats 8559 firstDay = dates[0].getUTCDay(); 8560 for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow += 1) { 8561 if (dates[daysPerRow].getUTCDay() === firstDay) { 8562 break; 8563 } 8564 } 8565 rowCnt = Math.ceil(dates.length / daysPerRow); 8566 } 8567 else { 8568 rowCnt = 1; 8569 daysPerRow = dates.length; 8570 } 8571 this.rowCnt = rowCnt; 8572 this.colCnt = daysPerRow; 8573 this.daySeries = daySeries; 8574 this.cells = this.buildCells(); 8575 this.headerDates = this.buildHeaderDates(); 8576 } 8577 DayTableModel.prototype.buildCells = function () { 8578 var rows = []; 8579 for (var row = 0; row < this.rowCnt; row += 1) { 8580 var cells = []; 8581 for (var col = 0; col < this.colCnt; col += 1) { 8582 cells.push(this.buildCell(row, col)); 8583 } 8584 rows.push(cells); 8585 } 8586 return rows; 8587 }; 8588 DayTableModel.prototype.buildCell = function (row, col) { 8589 var date = this.daySeries.dates[row * this.colCnt + col]; 8590 return { 8591 key: date.toISOString(), 8592 date: date, 8593 }; 8594 }; 8595 DayTableModel.prototype.buildHeaderDates = function () { 8596 var dates = []; 8597 for (var col = 0; col < this.colCnt; col += 1) { 8598 dates.push(this.cells[0][col].date); 8599 } 8600 return dates; 8601 }; 8602 DayTableModel.prototype.sliceRange = function (range) { 8603 var colCnt = this.colCnt; 8604 var seriesSeg = this.daySeries.sliceRange(range); 8605 var segs = []; 8606 if (seriesSeg) { 8607 var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex; 8608 var index = firstIndex; 8609 while (index <= lastIndex) { 8610 var row = Math.floor(index / colCnt); 8611 var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1); 8612 segs.push({ 8613 row: row, 8614 firstCol: index % colCnt, 8615 lastCol: (nextIndex - 1) % colCnt, 8616 isStart: seriesSeg.isStart && index === firstIndex, 8617 isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex, 8618 }); 8619 index = nextIndex; 8620 } 8621 } 8622 return segs; 8623 }; 8624 return DayTableModel; 8625 }()); 8626 8627 var Slicer = /** @class */ (function () { 8628 function Slicer() { 8629 this.sliceBusinessHours = memoize(this._sliceBusinessHours); 8630 this.sliceDateSelection = memoize(this._sliceDateSpan); 8631 this.sliceEventStore = memoize(this._sliceEventStore); 8632 this.sliceEventDrag = memoize(this._sliceInteraction); 8633 this.sliceEventResize = memoize(this._sliceInteraction); 8634 this.forceDayIfListItem = false; // hack 8635 } 8636 Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, context) { 8637 var extraArgs = []; 8638 for (var _i = 4; _i < arguments.length; _i++) { 8639 extraArgs[_i - 4] = arguments[_i]; 8640 } 8641 var eventUiBases = props.eventUiBases; 8642 var eventSegs = this.sliceEventStore.apply(this, __spreadArray([props.eventStore, eventUiBases, dateProfile, nextDayThreshold], extraArgs)); 8643 return { 8644 dateSelectionSegs: this.sliceDateSelection.apply(this, __spreadArray([props.dateSelection, eventUiBases, context], extraArgs)), 8645 businessHourSegs: this.sliceBusinessHours.apply(this, __spreadArray([props.businessHours, dateProfile, nextDayThreshold, context], extraArgs)), 8646 fgEventSegs: eventSegs.fg, 8647 bgEventSegs: eventSegs.bg, 8648 eventDrag: this.sliceEventDrag.apply(this, __spreadArray([props.eventDrag, eventUiBases, dateProfile, nextDayThreshold], extraArgs)), 8649 eventResize: this.sliceEventResize.apply(this, __spreadArray([props.eventResize, eventUiBases, dateProfile, nextDayThreshold], extraArgs)), 8650 eventSelection: props.eventSelection, 8651 }; // TODO: give interactionSegs? 8652 }; 8653 Slicer.prototype.sliceNowDate = function (// does not memoize 8654 date, context) { 8655 var extraArgs = []; 8656 for (var _i = 2; _i < arguments.length; _i++) { 8657 extraArgs[_i - 2] = arguments[_i]; 8658 } 8659 return this._sliceDateSpan.apply(this, __spreadArray([{ range: { start: date, end: addMs(date, 1) }, allDay: false }, 8660 {}, 8661 context], extraArgs)); 8662 }; 8663 Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, context) { 8664 var extraArgs = []; 8665 for (var _i = 4; _i < arguments.length; _i++) { 8666 extraArgs[_i - 4] = arguments[_i]; 8667 } 8668 if (!businessHours) { 8669 return []; 8670 } 8671 return this._sliceEventStore.apply(this, __spreadArray([expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context), 8672 {}, 8673 dateProfile, 8674 nextDayThreshold], extraArgs)).bg; 8675 }; 8676 Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold) { 8677 var extraArgs = []; 8678 for (var _i = 4; _i < arguments.length; _i++) { 8679 extraArgs[_i - 4] = arguments[_i]; 8680 } 8681 if (eventStore) { 8682 var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 8683 return { 8684 bg: this.sliceEventRanges(rangeRes.bg, extraArgs), 8685 fg: this.sliceEventRanges(rangeRes.fg, extraArgs), 8686 }; 8687 } 8688 return { bg: [], fg: [] }; 8689 }; 8690 Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold) { 8691 var extraArgs = []; 8692 for (var _i = 4; _i < arguments.length; _i++) { 8693 extraArgs[_i - 4] = arguments[_i]; 8694 } 8695 if (!interaction) { 8696 return null; 8697 } 8698 var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 8699 return { 8700 segs: this.sliceEventRanges(rangeRes.fg, extraArgs), 8701 affectedInstances: interaction.affectedEvents.instances, 8702 isEvent: interaction.isEvent, 8703 }; 8704 }; 8705 Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, context) { 8706 var extraArgs = []; 8707 for (var _i = 3; _i < arguments.length; _i++) { 8708 extraArgs[_i - 3] = arguments[_i]; 8709 } 8710 if (!dateSpan) { 8711 return []; 8712 } 8713 var eventRange = fabricateEventRange(dateSpan, eventUiBases, context); 8714 var segs = this.sliceRange.apply(this, __spreadArray([dateSpan.range], extraArgs)); 8715 for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) { 8716 var seg = segs_1[_a]; 8717 seg.eventRange = eventRange; 8718 } 8719 return segs; 8720 }; 8721 /* 8722 "complete" seg means it has component and eventRange 8723 */ 8724 Slicer.prototype.sliceEventRanges = function (eventRanges, extraArgs) { 8725 var segs = []; 8726 for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) { 8727 var eventRange = eventRanges_1[_i]; 8728 segs.push.apply(segs, this.sliceEventRange(eventRange, extraArgs)); 8729 } 8730 return segs; 8731 }; 8732 /* 8733 "complete" seg means it has component and eventRange 8734 */ 8735 Slicer.prototype.sliceEventRange = function (eventRange, extraArgs) { 8736 var dateRange = eventRange.range; 8737 // hack to make multi-day events that are being force-displayed as list-items to take up only one day 8738 if (this.forceDayIfListItem && eventRange.ui.display === 'list-item') { 8739 dateRange = { 8740 start: dateRange.start, 8741 end: addDays(dateRange.start, 1), 8742 }; 8743 } 8744 var segs = this.sliceRange.apply(this, __spreadArray([dateRange], extraArgs)); 8745 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 8746 var seg = segs_2[_i]; 8747 seg.eventRange = eventRange; 8748 seg.isStart = eventRange.isStart && seg.isStart; 8749 seg.isEnd = eventRange.isEnd && seg.isEnd; 8750 } 8751 return segs; 8752 }; 8753 return Slicer; 8754 }()); 8755 /* 8756 for incorporating slotMinTime/slotMaxTime if appropriate 8757 TODO: should be part of DateProfile! 8758 TimelineDateProfile already does this btw 8759 */ 8760 function computeActiveRange(dateProfile, isComponentAllDay) { 8761 var range = dateProfile.activeRange; 8762 if (isComponentAllDay) { 8763 return range; 8764 } 8765 return { 8766 start: addMs(range.start, dateProfile.slotMinTime.milliseconds), 8767 end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5), // 864e5 = ms in a day 8768 }; 8769 } 8770 8771 // high-level segmenting-aware tester functions 8772 // ------------------------------------------------------------------------------------------------------------------------ 8773 function isInteractionValid(interaction, dateProfile, context) { 8774 var instances = interaction.mutatedEvents.instances; 8775 for (var instanceId in instances) { 8776 if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) { 8777 return false; 8778 } 8779 } 8780 return isNewPropsValid({ eventDrag: interaction }, context); // HACK: the eventDrag props is used for ALL interactions 8781 } 8782 function isDateSelectionValid(dateSelection, dateProfile, context) { 8783 if (!rangeContainsRange(dateProfile.validRange, dateSelection.range)) { 8784 return false; 8785 } 8786 return isNewPropsValid({ dateSelection: dateSelection }, context); 8787 } 8788 function isNewPropsValid(newProps, context) { 8789 var calendarState = context.getCurrentData(); 8790 var props = __assign({ businessHours: calendarState.businessHours, dateSelection: '', eventStore: calendarState.eventStore, eventUiBases: calendarState.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps); 8791 return (context.pluginHooks.isPropsValid || isPropsValid)(props, context); 8792 } 8793 function isPropsValid(state, context, dateSpanMeta, filterConfig) {
8794 if (dateSpanMeta === void 0) { dateSpanMeta = {}; } 8795 if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) { 8796 return false; 8797 } 8798 if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) { 8799 return false; 8800 } 8801 return true; 8802 } 8803 // Moving Event Validation 8804 // ------------------------------------------------------------------------------------------------------------------------ 8805 function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) { 8806 var currentState = context.getCurrentData(); 8807 var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions 8808 var subjectEventStore = interaction.mutatedEvents; 8809 var subjectDefs = subjectEventStore.defs; 8810 var subjectInstances = subjectEventStore.instances; 8811 var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ? 8812 state.eventUiBases : 8813 { '': currentState.selectionConfig }); 8814 if (filterConfig) { 8815 subjectConfigs = mapHash(subjectConfigs, filterConfig); 8816 } 8817 // exclude the subject events. TODO: exclude defs too? 8818 var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); 8819 var otherDefs = otherEventStore.defs; 8820 var otherInstances = otherEventStore.instances; 8821 var otherConfigs = compileEventUis(otherDefs, state.eventUiBases); 8822 for (var subjectInstanceId in subjectInstances) { 8823 var subjectInstance = subjectInstances[subjectInstanceId]; 8824 var subjectRange = subjectInstance.range; 8825 var subjectConfig = subjectConfigs[subjectInstance.defId]; 8826 var subjectDef = subjectDefs[subjectInstance.defId]; 8827 // constraint 8828 if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) { 8829 return false; 8830 } 8831 // overlap 8832 var eventOverlap = context.options.eventOverlap; 8833 var eventOverlapFunc = typeof eventOverlap === 'function' ? eventOverlap : null; 8834 for (var otherInstanceId in otherInstances) { 8835 var otherInstance = otherInstances[otherInstanceId]; 8836 // intersect! evaluate 8837 if (rangesIntersect(subjectRange, otherInstance.range)) { 8838 var otherOverlap = otherConfigs[otherInstance.defId].overlap; 8839 // consider the other event's overlap. only do this if the subject event is a "real" event 8840 if (otherOverlap === false && interaction.isEvent) { 8841 return false; 8842 } 8843 if (subjectConfig.overlap === false) { 8844 return false; 8845 } 8846 if (eventOverlapFunc && !eventOverlapFunc(new EventApi(context, otherDefs[otherInstance.defId], otherInstance), // still event 8847 new EventApi(context, subjectDef, subjectInstance))) { 8848 return false; 8849 } 8850 } 8851 } 8852 // allow (a function) 8853 var calendarEventStore = currentState.eventStore; // need global-to-calendar, not local to component (splittable)state 8854 for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) { 8855 var subjectAllow = _a[_i]; 8856 var subjectDateSpan = __assign(__assign({}, dateSpanMeta), { range: subjectInstance.range, allDay: subjectDef.allDay }); 8857 var origDef = calendarEventStore.defs[subjectDef.defId]; 8858 var origInstance = calendarEventStore.instances[subjectInstanceId]; 8859 var eventApi = void 0; 8860 if (origDef) { // was previously in the calendar 8861 eventApi = new EventApi(context, origDef, origInstance); 8862 } 8863 else { // was an external event 8864 eventApi = new EventApi(context, subjectDef); // no instance, because had no dates 8865 } 8866 if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) { 8867 return false; 8868 } 8869 } 8870 } 8871 return true; 8872 } 8873 // Date Selection Validation 8874 // ------------------------------------------------------------------------------------------------------------------------ 8875 function isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) { 8876 var relevantEventStore = state.eventStore; 8877 var relevantDefs = relevantEventStore.defs; 8878 var relevantInstances = relevantEventStore.instances; 8879 var selection = state.dateSelection; 8880 var selectionRange = selection.range; 8881 var selectionConfig = context.getCurrentData().selectionConfig; 8882 if (filterConfig) { 8883 selectionConfig = filterConfig(selectionConfig); 8884 } 8885 // constraint 8886 if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) { 8887 return false; 8888 } 8889 // overlap 8890 var selectOverlap = context.options.selectOverlap; 8891 var selectOverlapFunc = typeof selectOverlap === 'function' ? selectOverlap : null; 8892 for (var relevantInstanceId in relevantInstances) { 8893 var relevantInstance = relevantInstances[relevantInstanceId]; 8894 // intersect! evaluate 8895 if (rangesIntersect(selectionRange, relevantInstance.range)) { 8896 if (selectionConfig.overlap === false) { 8897 return false; 8898 } 8899 if (selectOverlapFunc && !selectOverlapFunc(new EventApi(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) { 8900 return false; 8901 } 8902 } 8903 } 8904 // allow (a function) 8905 for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) { 8906 var selectionAllow = _a[_i]; 8907 var fullDateSpan = __assign(__assign({}, dateSpanMeta), selection); 8908 if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) { 8909 return false; 8910 } 8911 } 8912 return true; 8913 } 8914 // Constraint Utils 8915 // ------------------------------------------------------------------------------------------------------------------------ 8916 function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) { 8917 for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) { 8918 var constraint = constraints_1[_i]; 8919 if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) { 8920 return false; 8921 } 8922 } 8923 return true; 8924 } 8925 function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours 8926 otherEventStore, // for if constraint is an even group ID 8927 businessHoursUnexpanded, // for if constraint is 'businessHours' 8928 context) { 8929 if (constraint === 'businessHours') { 8930 return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context)); 8931 } 8932 if (typeof constraint === 'string') { // an group ID 8933 return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) { return eventDef.groupId === constraint; })); 8934 } 8935 if (typeof constraint === 'object' && constraint) { // non-null object 8936 return eventStoreToRanges(expandRecurring(constraint, subjectRange, context)); 8937 } 8938 return []; // if it's false 8939 } 8940 // TODO: move to event-store file? 8941 function eventStoreToRanges(eventStore) { 8942 var instances = eventStore.instances; 8943 var ranges = []; 8944 for (var instanceId in instances) { 8945 ranges.push(instances[instanceId].range); 8946 } 8947 return ranges; 8948 } 8949 // TODO: move to geom file? 8950 function anyRangesContainRange(outerRanges, innerRange) { 8951 for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) { 8952 var outerRange = outerRanges_1[_i]; 8953 if (rangeContainsRange(outerRange, innerRange)) { 8954 return true; 8955 } 8956 } 8957 return false; 8958 } 8959 8960 var VISIBLE_HIDDEN_RE = /^(visible|hidden)$/; 8961 var Scroller = /** @class */ (function (_super) { 8962 __extends(Scroller, _super); 8963 function Scroller() { 8964 var _this = _super !== null && _super.apply(this, arguments) || this; 8965 _this.handleEl = function (el) { 8966 _this.el = el; 8967 setRef(_this.props.elRef, el); 8968 }; 8969 return _this; 8970 } 8971 Scroller.prototype.render = function () { 8972 var props = this.props; 8973 var liquid = props.liquid, liquidIsAbsolute = props.liquidIsAbsolute; 8974 var isAbsolute = liquid && liquidIsAbsolute; 8975 var className = ['fc-scroller']; 8976 if (liquid) { 8977 if (liquidIsAbsolute) { 8978 className.push('fc-scroller-liquid-absolute'); 8979 } 8980 else { 8981 className.push('fc-scroller-liquid'); 8982 } 8983 } 8984 return (createElement("div", { ref: this.handleEl, className: className.join(' '), style: { 8985 overflowX: props.overflowX, 8986 overflowY: props.overflowY, 8987 left: (isAbsolute && -(props.overcomeLeft || 0)) || '', 8988 right: (isAbsolute && -(props.overcomeRight || 0
8988)) || '', 8989 bottom: (isAbsolute && -(props.overcomeBottom || 0)) || '', 8990 marginLeft: (!isAbsolute && -(props.overcomeLeft || 0)) || '', 8991 marginRight: (!isAbsolute && -(props.overcomeRight || 0)) || '', 8992 marginBottom: (!isAbsolute && -(props.overcomeBottom || 0)) || '', 8993 maxHeight: props.maxHeight || '', 8994 } }, props.children)); 8995 }; 8996 Scroller.prototype.needsXScrolling = function () { 8997 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 8998 return false; 8999 } 9000 // testing scrollWidth>clientWidth is unreliable cross-browser when pixel heights aren't integers. 9001 // much more reliable to see if children are taller than the scroller, even tho doesn't account for 9002 // inner-child margins and absolute positioning 9003 var el = this.el; 9004 var realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth(); 9005 var children = el.children; 9006 for (var i = 0; i < children.length; i += 1) { 9007 var childEl = children[i]; 9008 if (childEl.getBoundingClientRect().width > realClientWidth) { 9009 return true; 9010 } 9011 } 9012 return false; 9013 }; 9014 Scroller.prototype.needsYScrolling = function () { 9015 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 9016 return false; 9017 } 9018 // testing scrollHeight>clientHeight is unreliable cross-browser when pixel heights aren't integers. 9019 // much more reliable to see if children are taller than the scroller, even tho doesn't account for 9020 // inner-child margins and absolute positioning 9021 var el = this.el; 9022 var realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth(); 9023 var children = el.children; 9024 for (var i = 0; i < children.length; i += 1) { 9025 var childEl = children[i]; 9026 if (childEl.getBoundingClientRect().height > realClientHeight) { 9027 return true; 9028 } 9029 } 9030 return false; 9031 }; 9032 Scroller.prototype.getXScrollbarWidth = function () { 9033 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 9034 return 0; 9035 } 9036 return this.el.offsetHeight - this.el.clientHeight; // only works because we guarantee no borders. TODO: add to CSS with important? 9037 }; 9038 Scroller.prototype.getYScrollbarWidth = function () { 9039 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 9040 return 0; 9041 } 9042 return this.el.offsetWidth - this.el.clientWidth; // only works because we guarantee no borders. TODO: add to CSS with important? 9043 }; 9044 return Scroller; 9045 }(BaseComponent)); 9046 9047 /* 9048 TODO: somehow infer OtherArgs from masterCallback? 9049 TODO: infer RefType from masterCallback if provided 9050 */ 9051 var RefMap = /** @class */ (function () { 9052 function RefMap(masterCallback) { 9053 var _this = this; 9054 this.masterCallback = masterCallback; 9055 this.currentMap = {}; 9056 this.depths = {}; 9057 this.callbackMap = {}; 9058 this.handleValue = function (val, key) { 9059 var _a = _this, depths = _a.depths, currentMap = _a.currentMap; 9060 var removed = false; 9061 var added = false; 9062 if (val !== null) { 9063 // for bug... ACTUALLY: can probably do away with this now that callers don't share numeric indices anymore 9064 removed = (key in currentMap); 9065 currentMap[key] = val; 9066 depths[key] = (depths[key] || 0) + 1; 9067 added = true; 9068 } 9069 else { 9070 depths[key] -= 1; 9071 if (!depths[key]) { 9072 delete currentMap[key]; 9073 delete _this.callbackMap[key]; 9074 removed = true; 9075 } 9076 } 9077 if (_this.masterCallback) { 9078 if (removed) { 9079 _this.masterCallback(null, String(key)); 9080 } 9081 if (added) { 9082 _this.masterCallback(val, String(key)); 9083 } 9084 } 9085 }; 9086 } 9087 RefMap.prototype.createRef = function (key) { 9088 var _this = this; 9089 var refCallback = this.callbackMap[key]; 9090 if (!refCallback) { 9091 refCallback = this.callbackMap[key] = function (val) { 9092 _this.handleValue(val, String(key)); 9093 }; 9094 } 9095 return refCallback; 9096 }; 9097 // TODO: check callers that don't care about order. should use getAll instead 9098 // NOTE: this method has become less valuable now that we are encouraged to map order by some other index 9099 // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and "collect" 9100 RefMap.prototype.collect = function (startIndex, endIndex, step) { 9101 return collectFromHash(this.currentMap, startIndex, endIndex, step); 9102 }; 9103 RefMap.prototype.getAll = function () { 9104 return hashValuesToArray(this.currentMap); 9105 }; 9106 return RefMap; 9107 }()); 9108 9109 function computeShrinkWidth(chunkEls) { 9110 var shrinkCells = findElements(chunkEls, '.fc-scrollgrid-shrink'); 9111 var largestWidth = 0; 9112 for (var _i = 0, shrinkCells_1 = shrinkCells; _i < shrinkCells_1.length; _i++) { 9113 var shrinkCell = shrinkCells_1[_i]; 9114 largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell)); 9115 } 9116 return Math.ceil(largestWidth); // <table> elements work best with integers. round up to ensure contents fits 9117 } 9118 function getSectionHasLiquidHeight(props, sectionConfig) { 9119 return props.liquid && sectionConfig.liquid; // does the section do liquid-height? (need to have whole scrollgrid liquid-height as well) 9120 } 9121 function getAllowYScrolling(props, sectionConfig) { 9122 return sectionConfig.maxHeight != null || // if its possible for the height to max out, we might need scrollbars 9123 getSectionHasLiquidHeight(props, sectionConfig); // if the section is liquid height, it might condense enough to require scrollbars 9124 } 9125 // TODO: ONLY use `arg`. force out internal function to use same API 9126 function renderChunkContent(sectionConfig, chunkConfig, arg, isHeader) { 9127 var expandRows = arg.expandRows; 9128 var content = typeof chunkConfig.content === 'function' ? 9129 chunkConfig.content(arg) : 9130 createElement('table', { 9131 role: 'presentation', 9132 className: [ 9133 chunkConfig.tableClassName, 9134 sectionConfig.syncRowHeights ? 'fc-scrollgrid-sync-table' : '', 9135 ].join(' '), 9136 style: { 9137 minWidth: arg.tableMinWidth, 9138 width: arg.clientWidth, 9139 height: expandRows ? arg.clientHeight : '', // css `height` on a <table> serves as a min-height 9140 }, 9141 }, arg.tableColGroupNode, createElement(isHeader ? 'thead' : 'tbody', { 9142 role: 'presentation', 9143 }, typeof chunkConfig.rowContent === 'function' 9144 ? chunkConfig.rowContent(arg) 9145 : chunkConfig.rowContent)); 9146 return content; 9147 } 9148 function isColPropsEqual(cols0, cols1) { 9149 return isArraysEqual(cols0, cols1, isPropsEqual); 9150 } 9151 function renderMicroColGroup(cols, shrinkWidth) { 9152 var colNodes = []; 9153 /* 9154 for ColProps with spans, it would have been great to make a single <col span=""> 9155 HOWEVER, Chrome was getting messing up distributing the width to <td>/<th> elements with colspans. 9156 SOLUTION: making individual <col> elements makes Chrome behave. 9157 */ 9158 for (var _i = 0, cols_1 = cols; _i < cols_1.length; _i++) { 9159 var colProps = cols_1[_i]; 9160 var span = colProps.span || 1; 9161 for (var i = 0; i < span; i += 1) {
9162 colNodes.push(createElement("col", { style: { 9163 width: colProps.width === 'shrink' ? sanitizeShrinkWidth(shrinkWidth) : (colProps.width || ''), 9164 minWidth: colProps.minWidth || '', 9165 } })); 9166 } 9167 } 9168 return createElement.apply(void 0, __spreadArray(['colgroup', {}], colNodes)); 9169 } 9170 function sanitizeShrinkWidth(shrinkWidth) { 9171 /* why 4? if we do 0, it will kill any border, which are needed for computeSmallestCellWidth 9172 4 accounts for 2 2-pixel borders. TODO: better solution? */ 9173 return shrinkWidth == null ? 4 : shrinkWidth; 9174 } 9175 function hasShrinkWidth(cols) { 9176 for (var _i = 0, cols_2 = cols; _i < cols_2.length; _i++) { 9177 var col = cols_2[_i]; 9178 if (col.width === 'shrink') { 9179 return true; 9180 } 9181 } 9182 return false; 9183 } 9184 function getScrollGridClassNames(liquid, context) { 9185 var classNames = [ 9186 'fc-scrollgrid', 9187 context.theme.getClass('table'), 9188 ]; 9189 if (liquid) { 9190 classNames.push('fc-scrollgrid-liquid'); 9191 } 9192 return classNames; 9193 } 9194 function getSectionClassNames(sectionConfig, wholeTableVGrow) { 9195 var classNames = [ 9196 'fc-scrollgrid-section', 9197 "fc-scrollgrid-section-" + sectionConfig.type, 9198 sectionConfig.className, // used? 9199 ]; 9200 if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) { 9201 classNames.push('fc-scrollgrid-section-liquid'); 9202 } 9203 if (sectionConfig.isSticky) { 9204 classNames.push('fc-scrollgrid-section-sticky'); 9205 } 9206 return classNames; 9207 }
9208 function renderScrollShim(arg) { 9209 return (createElement("div", { className: "fc-scrollgrid-sticky-shim", style: { 9210 width: arg.clientWidth, 9211 minWidth: arg.tableMinWidth, 9212 } })); 9213 } 9214 function getStickyHeaderDates(options) { 9215 var stickyHeaderDates = options.stickyHeaderDates; 9216 if (stickyHeaderDates == null || stickyHeaderDates === 'auto') { 9217 stickyHeaderDates = options.height === 'auto' || options.viewHeight === 'auto'; 9218 } 9219 return stickyHeaderDates; 9220 } 9221 function getStickyFooterScrollbar(options) { 9222 var stickyFooterScrollbar = options.stickyFooterScrollbar; 9223 if (stickyFooterScrollbar == null || stickyFooterScrollbar === 'auto') { 9224 stickyFooterScrollbar = options.height === 'auto' || options.viewHeight === 'auto'; 9225 } 9226 return stickyFooterScrollbar; 9227 } 9228 9229 var SimpleScrollGrid = /** @class */ (function (_super) { 9230 __extends(SimpleScrollGrid, _super); 9231 function SimpleScrollGrid() { 9232 var _this = _super !== null && _super.apply(this, arguments) || this; 9233 _this.processCols = memoize(function (a) { return a; }, isColPropsEqual); // so we get same `cols` props every time 9234 // yucky to memoize VNodes, but much more efficient for consumers 9235 _this.renderMicroColGroup = memoize(renderMicroColGroup); 9236 _this.scrollerRefs = new RefMap(); 9237 _this.scrollerElRefs = new RefMap(_this._handleScrollerEl.bind(_this)); 9238 _this.state = { 9239 shrinkWidth: null, 9240 forceYScrollbars: false, 9241 scrollerClientWidths: {}, 9242 scrollerClientHeights: {}, 9243 }; 9244 // TODO: can do a really simple print-view. dont need to join rows 9245 _this.handleSizing = function () { 9246 _this.safeSetState(__assign({ shrinkWidth: _this.computeShrinkWidth() }, _this.computeScrollerDims())); 9247 }; 9248 return _this; 9249 } 9250 SimpleScrollGrid.prototype.render = function () { 9251 var _a = this, props = _a.props, state = _a.state, context = _a.context; 9252 var sectionConfigs = props.sections || []; 9253 var cols = this.processCols(props.cols); 9254 var microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth); 9255 var classNames = getScrollGridClassNames(props.liquid, context); 9256 if (props.collapsibleWidth) { 9257 classNames.push('fc-scrollgrid-collapsible'); 9258 } 9259 // TODO: make DRY 9260 var configCnt = sectionConfigs.length; 9261 var configI = 0; 9262 var currentConfig; 9263 var headSectionNodes = []; 9264 var bodySectionNodes = []; 9265 var footSectionNodes = []; 9266 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') { 9267 headSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true)); 9268 configI += 1; 9269 } 9270 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'body') { 9271 bodySectionNodes.push(this.renderSection(currentConfig, microColGroupNode, false)); 9272 configI += 1; 9273 } 9274 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'footer') { 9275 footSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true)); 9276 configI += 1; 9277 } 9278 // firefox bug: when setting height on table and there is a thead or tfoot, 9279 // the necessary height:100% on the liquid-height body section forces the *whole* table to be taller. (bug #5524) 9280 // use getCanVGrowWithinCell as a way to detect table-stupid firefox. 9281 // if so, use a simpler dom structure, jam everything into a lone tbody. 9282 var isBuggy = !getCanVGrowWithinCell(); 9283 var roleAttrs = { role: 'rowgroup' }; 9284 return createElement('table', { 9285 role: 'grid', 9286 className: classNames.join(' '), 9287 style: { height: props.height }, 9288 }, Boolean(!isBuggy && headSectionNodes.length) && createElement.apply(void 0, __spreadArray(['thead', roleAttrs], headSectionNodes
9288)), 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))); 9289 }; 9290 SimpleScrollGrid.prototype.renderSection = function (sectionConfig, microColGroupNode, isHeader) { 9291 if ('outerContent' in sectionConfig) { 9292 return (createElement(Fragment, { key: sectionConfig.key }, sectionConfig.outerContent)); 9293 } 9294 return (createElement("tr", { key: sectionConfig.key, role: "presentation", className: getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, this.renderChunkTd(sectionConfig, microColGroupNode, sectionConfig.chunk, isHeader))); 9295 }; 9296 SimpleScrollGrid.prototype.renderChunkTd = function (sectionConfig, microColGroupNode, chunkConfig, isHeader) { 9297 if ('outerContent' in chunkConfig) { 9298 return chunkConfig.outerContent; 9299 } 9300 var props = this.props; 9301 var _a = this.state, forceYScrollbars = _a.forceYScrollbars, scrollerClientWidths = _a.scrollerClientWidths, scrollerClientHeights = _a.scrollerClientHeights; 9302 var needsYScrolling = getAllowYScrolling(props, sectionConfig); // TODO: do lazily. do in section config? 9303 var isLiquid = getSectionHasLiquidHeight(props, sectionConfig); 9304 // for `!props.liquid` - is WHOLE scrollgrid natural height? 9305 // TODO: do same thing in advanced scrollgrid? prolly not b/c always has horizontal scrollbars 9306 var overflowY = !props.liquid ? 'visible' : 9307 forceYScrollbars ? 'scroll' : 9308 !needsYScrolling ? 'hidden' : 9309 'auto'; 9310 var sectionKey = sectionConfig.key; 9311 var content = renderChunkContent(sectionConfig, chunkConfig, { 9312 tableColGroupNode: microColGroupNode, 9313 tableMinWidth: '', 9314 clientWidth: (!props.collapsibleWidth && scrollerClientWidths[sectionKey] !== undefined) ? scrollerClientWidths[sectionKey] : null, 9315 clientHeight: scrollerClientHeights[sectionKey] !== undefined ? scrollerClientHeights[sectionKey] : null, 9316 expandRows: sectionConfig.expandRows, 9317 syncRowHeights: false, 9318 rowSyncHeights: [], 9319 reportRowHeightChange: function () { }, 9320 }, isHeader); 9321 return createElement(isHeader ? 'th' : 'td', { 9322 ref: chunkConfig.elRef, 9323 role: 'presentation', 9324 }, createElement("div", { className: "fc-scroller-harness" + (isLiquid ? ' fc-scroller-harness-liquid' : '') }, 9325 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 9326 : true }, content))); 9327 }; 9328 SimpleScrollGrid.prototype._handleScrollerEl = function (scrollerEl, key) { 9329 var section = getSectionByKey(this.props.sections, key); 9330 if (section) { 9331 setRef(section.chunk.scrollerElRef, scrollerEl); 9332 } 9333 }; 9334 SimpleScrollGrid.prototype.componentDidMount = function () { 9335 this.handleSizing(); 9336 this.context.addResizeHandler(this.handleSizing); 9337 }; 9338 SimpleScrollGrid.prototype.componentDidUpdate = function () { 9339 // TODO: need better solution when state contains non-sizing things 9340 this.handleSizing(); 9341 }; 9342 SimpleScrollGrid.prototype.componentWillUnmount = function () { 9343 this.context.removeResizeHandler(this.handleSizing); 9344 }; 9345 SimpleScrollGrid.prototype.computeShrinkWidth = function () { 9346 return hasShrinkWidth(this.props.cols) 9347 ? computeShrinkWidth(this.scrollerElRefs.getAll()) 9348 : 0; 9349 }; 9350 SimpleScrollGrid.prototype.computeScrollerDims = function () { 9351 var scrollbarWidth = getScrollbarWidths(); 9352 var _a = this, scrollerRefs = _a.scrollerRefs, scrollerElRefs = _a.scrollerElRefs; 9353 var forceYScrollbars = false;
9354 var scrollerClientWidths = {}; 9355 var scrollerClientHeights = {}; 9356 for (var sectionKey in scrollerRefs.currentMap) { 9357 var scroller = scrollerRefs.currentMap[sectionKey]; 9358 if (scroller && scroller.needsYScrolling()) { 9359 forceYScrollbars = true; 9360 break; 9361 } 9362 } 9363 for (var _i = 0, _b = this.props.sections; _i < _b.length; _i++) { 9364 var section = _b[_i]; 9365 var sectionKey = section.key; 9366 var scrollerEl = scrollerElRefs.currentMap[sectionKey]; 9367 if (scrollerEl) { 9368 var harnessEl = scrollerEl.parentNode; // TODO: weird way to get this. need harness b/c doesn't include table borders 9369 scrollerClientWidths[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars 9370 ? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future 9371 : 0)); 9372 scrollerClientHeights[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().height); 9373 } 9374 } 9375 return { forceYScrollbars: forceYScrollbars, scrollerClientWidths: scrollerClientWidths, scrollerClientHeights: scrollerClientHeights }; 9376 }; 9377 return SimpleScrollGrid; 9378 }(BaseComponent)); 9379 SimpleScrollGrid.addStateEquality({ 9380 scrollerClientWidths: isPropsEqual, 9381 scrollerClientHeights: isPropsEqual, 9382 }); 9383 function getSectionByKey(sections, key) { 9384 for (var _i = 0, sections_1 = sections; _i < sections_1.length; _i++) { 9385 var section = sections_1[_i]; 9386 if (section.key === key) { 9387 return section; 9388 } 9389 } 9390 return null; 9391 } 9392 9393 var EventRoot = /** @class */ (function (_super) { 9394 __extends(EventRoot, _super); 9395 function EventRoot() { 9396 var _this = _super !== null && _super.apply(this, arguments) || this; 9397 _this.elRef = createRef(); 9398 return _this; 9399 } 9400 EventRoot.prototype.render = function () { 9401 var _a = this, props = _a.props, context = _a.context; 9402 var options = context.options; 9403 var seg = props.seg; 9404 var eventRange = seg.eventRange; 9405 var ui = eventRange.ui; 9406 var hookProps = { 9407 event: new EventApi(context, eventRange.def, eventRange.instance), 9408 view: context.viewApi, 9409 timeText: props.timeText, 9410 textColor: ui.textColor, 9411 backgroundColor: ui.backgroundColor, 9412 borderColor: ui.borderColor, 9413 isDraggable: !props.disableDragging && computeSegDraggable(seg, context), 9414 isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context), 9415 isEndResizable: !props.disableResizing && computeSegEndResizable(seg), 9416 isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting), 9417 isStart: Boolean(seg.isStart), 9418 isEnd: Boolean(seg.isEnd), 9419 isPast: Boolean(props.isPast), 9420 isFuture: Boolean(props.isFuture), 9421 isToday: Boolean(props.isToday), 9422 isSelected: Boolean(props.isSelected), 9423 isDragging: Boolean(props.isDragging), 9424 isResizing: Boolean(props.isResizing), 9425 }; 9426 var standardClassNames = getEventClassNames(hookProps).concat(ui.classNames); 9427 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
9427oncat(customClassNames), innerElRef, innerContent, hookProps); })); 9428 }; 9429 EventRoot.prototype.componentDidMount = function () { 9430 setElSeg(this.elRef.current, this.props.seg); 9431 }; 9432 /* 9433 need to re-assign seg to the element if seg changes, even if the element is the same 9434 */ 9435 EventRoot.prototype.componentDidUpdate = function (prevProps) { 9436 var seg = this.props.seg; 9437 if (seg !== prevProps.seg) { 9438 setElSeg(this.elRef.current, seg); 9439 } 9440 }; 9441 return EventRoot; 9442 }(BaseComponent)); 9443 9444 // should not be a purecomponent 9445 var StandardEvent = /** @class */ (function (_super) { 9446 __extends(StandardEvent, _super); 9447 function StandardEvent() { 9448 return _super !== null && _super.apply(this, arguments) || this; 9449 } 9450 StandardEvent.prototype.render = function () { 9451 var _a = this, props = _a.props, context = _a.context; 9452 var seg = props.seg; 9453 var timeFormat = context.options.eventTimeFormat || props.defaultTimeFormat; 9454 var timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd); 9455 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: { 9456 borderColor: hookProps.borderColor, 9457 backgroundColor: hookProps.backgroundColor, 9458 }, ref: rootElRef }, getSegAnchorAttrs(seg, context)), 9459 createElement("div", { className: "fc-event-main", ref: innerElRef, style: { color: hookProps.textColor } }, innerContent), 9460 hookProps.isStartResizable && 9461 createElement("div", { className: "fc-event-resizer fc-event-resizer-start" }), 9462 hookProps.isEndResizable && 9463 createElement("div", { className: "fc-event-resizer fc-event-resizer-end" }))); })); 9464 }; 9465 return StandardEvent; 9466 }(BaseComponent)); 9467 function renderInnerContent$4(innerProps) { 9468 return (createElement("div", { className: "fc-event-main-frame" }, 9469 innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)), 9470 createElement("div", { className: "fc-event-title-container" }, 9471 createElement("div", { className: "fc-event-title fc-sticky" }, innerProps.event.title || createElement(Fragment, null, "\u00A0"))))); 9472 } 9473 9474 var NowIndicatorRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) { 9475 var options = context.options; 9476 var hookProps = { 9477 isAxis: props.isAxis, 9478 date: context.dateEnv.toDate(props.date), 9479 view: context.viewApi, 9480 }; 9481 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.nowIndicatorClassNames, content: options.nowIndicatorContent, didMount: options.nowIndicatorDidMount, willUnmount: options.nowIndicatorWillUnmount }, props.children)); 9482 })); }; 9483 9484 var DAY_NUM_FORMAT = createFormatter({ day: 'numeric' }); 9485 var DayCellContent = /** @class */ (function (_super) { 9486 __extends(DayCellContent, _super); 9487 function DayCellContent() { 9488 return _super !== null && _super.apply(this, arguments) || this; 9489 } 9490 DayCellContent.prototype.render = function () { 9491 var _a = this, props = _a.props, context = _a.context; 9492 var options = context.options; 9493 var hookProps = refineDayCellHookProps({ 9494 date: props.date, 9495 dateProfile: props.dateProfile, 9496 todayRange: props.todayRange, 9497 showDayNumber: props.showDayNumber, 9498 extraProps: props.extraHookProps, 9499 viewApi: context.viewApi, 9500 dateEnv: context.dateEnv, 9501 }); 9502 return (createElement(ContentHook, { hookProps: hookProps, content: options.dayCellContent, defaultContent: props.defaultContent }, props.children)); 9503 }; 9504 return DayCellContent; 9505 }(BaseComponent)); 9506 function refineDayCellHookProps(raw) { 9507 var date = raw.date, dateEnv = raw.dateEnv;
9508 var dayMeta = getDateMeta(date, raw.todayRange, null, raw.dateProfile); 9509 return __assign(__assign(__assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), { dayNumberText: raw.showDayNumber ? dateEnv.format(date, DAY_NUM_FORMAT) : '' }), raw.extraProps); 9510 } 9511 9512 var DayCellRoot = /** @class */ (function (_super) { 9513 __extends(DayCellRoot, _super); 9514 function DayCellRoot() { 9515 var _this = _super !== null && _super.apply(this, arguments) || this; 9516 _this.refineHookProps = memoizeObjArg(refineDayCellHookProps); 9517 _this.normalizeClassNames = buildClassNameNormalizer(); 9518 return _this; 9519 } 9520 DayCellRoot.prototype.render = function () { 9521 var _a = this, props = _a.props, context = _a.context; 9522 var options = context.options; 9523 var hookProps = this.refineHookProps({ 9524 date: props.date, 9525 dateProfile: props.dateProfile, 9526 todayRange: props.todayRange, 9527 showDayNumber: props.showDayNumber, 9528 extraProps: props.extraHookProps, 9529 viewApi: context.viewApi, 9530 dateEnv: context.dateEnv, 9531 }); 9532 var classNames = getDayClassNames(hookProps, context.theme).concat(hookProps.isDisabled 9533 ? [] // don't use custom classNames if disabled 9534 : this.normalizeClassNames(options.dayCellClassNames, hookProps)); 9535 var dataAttrs = hookProps.isDisabled ? {} : { 9536 'data-date': formatDayString(props.date), 9537 }; 9538 return (createElement(MountHook, { hookProps: hookProps, didMount: options.dayCellDidMount, willUnmount: options.dayCellWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, classNames, dataAttrs, hookProps.isDisabled); })); 9539 }; 9540 return DayCellRoot; 9541 }(BaseComponent)); 9542 9543 function renderFill(fillType) { 9544 return (createElement("div", { className: "fc-" + fillType })); 9545 } 9546 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: { 9547 backgroundColor: hookProps.backgroundColor, 9548 } }, innerContent)); })); }; 9549 function renderInnerContent$3(props) { 9550 var title = props.event.title; 9551 return title && (createElement("div", { className: "fc-event-title" }, props.event.title)); 9552 } 9553 9554 var WeekNumberRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) { 9555 var dateEnv = context.dateEnv, options = context.options; 9556 var date = props.date; 9557 var format = options.weekNumberFormat || props.defaultFormat; 9558 var num = dateEnv.computeWeekNumber(date); // TODO: somehow use for formatting as well? 9559 var text = dateEnv.format(date, format); 9560 var hookProps = { num: num, text: text, date: date }; 9561 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.weekNumberClassNames, content: options.weekNumberContent, defaultContent: renderInner, didMount: options.weekNumberDidMount, willUnmount: options.weekNumberWillUnmount }, props.children)); 9562 })); }; 9563 function renderInner(innerProps) { 9564 return innerProps.text; 9565 } 9566 9567 var PADDING_FROM_VIEWPORT = 10; 9568 var Popover = /** @class */ (function (_super) { 9569 __extends(Popover, _super); 9570 function Popover() { 9571 var _this = _super !== null && _super.apply(this, arguments) || this; 9572 _this.state = { 9573 titleId: getUniqueDomId(), 9574 }; 9575 _this.handleRootEl = function (el) { 9576 _this.rootEl = el; 9577 if (_this.props.elRef) { 9578 setRef(_this.props.elRef, el); 9579 } 9580 }; 9581 // Triggered when the user clicks *anywhere* in the document, for the autoHide feature 9582 _this.handleDocumentMouseDown = function (ev) { 9583 // only hide the popover if the click happened outside the popover 9584 var target = getEventTargetViaRoot(ev); 9585 if (!_this.rootEl.contains(target)) { 9586 _this.handleCloseClick(); 9587 } 9588 }; 9589 _this.handleDocumentKeyDown = function (ev) { 9590 if (ev.key === 'Escape') { 9591 _this.handleCloseClick(); 9592 } 9593 }; 9594 _this.handleCloseClick = function () { 9595 var onClose = _this.props.onClose; 9596 if (onClose) { 9597 onClose(); 9598 } 9599 }; 9600 return _this; 9601 } 9602 Popover.prototype.render = function () { 9603 var _a = this.context, theme = _a.theme, options = _a.options; 9604 var _b = this, props = _b.props, state = _b.state; 9605 var classNames = [ 9606 'fc-popover', 9607 theme.getClass('popover'), 9608 ].concat(props.extraClassNames || []); 9609 return createPortal(createElement("div", __assign({ id: props.id, className: classNames.join(' '), "aria-labelledby": state.t
9609itleId }, props.extraAttrs, { ref: this.handleRootEl }), 9610 createElement("div", { className: 'fc-popover-header ' + theme.getClass('popoverHeader') }, 9611 createElement("span", { className: "fc-popover-title", id: state.titleId }, props.title), 9612 createElement("span", { className: 'fc-popover-close ' + theme.getIconClass('close'), title: options.closeHint, onClick: this.handleCloseClick })), 9613 createElement("div", { className: 'fc-popover-body ' + theme.getClass('popoverContent') }, props.children)), props.parentEl); 9614 }; 9615 Popover.prototype.componentDidMount = function () { 9616 document.addEventListener('mousedown', this.handleDocumentMouseDown); 9617 document.addEventListener('keydown', this.handleDocumentKeyDown); 9618 this.updateSize(); 9619 }; 9620 Popover.prototype.componentWillUnmount = function () { 9621 document.removeEventListener('mousedown', this.handleDocumentMouseDown); 9622 document.removeEventListener('keydown', this.handleDocumentKeyDown); 9623 }; 9624 Popover.prototype.updateSize = function () { 9625 var isRtl = this.context.isRtl; 9626 var _a = this.props, alignmentEl = _a.alignmentEl, alignGridTop = _a.alignGridTop; 9627 var rootEl = this.rootEl; 9628 var alignmentRect = computeClippedClientRect(alignmentEl); 9629 if (alignmentRect) { 9630 var popoverDims = rootEl.getBoundingClientRect(); 9631 // position relative to viewport 9632 var popoverTop = alignGridTop 9633 ? elementClosest(alignmentEl, '.fc-scrollgrid').getBoundingClientRect().top 9634 : alignmentRect.top; 9635 var popoverLeft = isRtl ? alignmentRect.right - popoverDims.width : alignmentRect.left; 9636 // constrain 9637 popoverTop = Math.max(popoverTop, PADDING_FROM_VIEWPORT); 9638 popoverLeft = Math.min(popoverLeft, document.documentElement.clientWidth - PADDING_FROM_VIEWPORT - popoverDims.width); 9639 popoverLeft = Math.max(popoverLeft, PADDING_FROM_VIEWPORT); 9640 var origin_1 = rootEl.offsetParent.getBoundingClientRect(); 9641 applyStyle(rootEl, { 9642 top: popoverTop - origin_1.top, 9643 left: popoverLeft - origin_1.left, 9644 }); 9645 } 9646 }; 9647 return Popover; 9648 }(BaseComponent)); 9649 9650 var MorePopover = /** @class */ (function (_super) { 9651 __extends(MorePopover, _super); 9652 function MorePopover() { 9653 var _this = _super !== null && _super.apply(this, arguments) || this; 9654 _this.handleRootEl = function (rootEl) { 9655 _this.rootEl = rootEl; 9656 if (rootEl) { 9657 _this.context.registerInteractiveComponent(_this, { 9658 el: rootEl, 9659 useEventCenter: false, 9660 }); 9661 } 9662 else { 9663 _this.context.unregisterInteractiveComponent(_this); 9664 } 9665 }; 9666 return _this; 9667 } 9668 MorePopover.prototype.render = function () { 9669 var _a = this.context, options = _a.options, dateEnv = _a.dateEnv; 9670 var props = this.props; 9671 var startDate = props.startDate, todayRange = props.todayRange, dateProfile = props.dateProfile; 9672 var title = dateEnv.format(startDate, options.dayPopoverFormat); 9673 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 }, 9674 createElement(DayCellContent, { date: startDate, dateProfile: dateProfile, todayRange: todayRange }, function (innerElRef, innerContent) { return (innerContent && 9675 createElement("div", { className: "fc-more-popover-misc", ref: innerElRef }, innerContent)); }), 9676 props.children)); })); 9677 }; 9678 MorePopover.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) { 9679 var _a = this, rootEl = _a.rootEl, props = _a.props; 9680 if (positionLeft >= 0 && positionLeft < elWidth && 9681 positionTop >= 0 && positionTop < elHeight) { 9682 return { 9683 dateProfile: props.dateProfile, 9684 dateSpan: __assign({ allDay: true, range: { 9685 start: props.startDate, 9686 end: props.endDate, 9687 } }, props.extraDateSpan), 9688 dayEl: rootEl, 9689 rect: { 9690 left: 0, 9691 top: 0, 9692 right: elWidth, 9693 bottom: elHeight, 9694 }, 9695 layer: 1, // important when comparing with hits from other components 9696 }; 9697 } 9698 return null; 9699 }; 9700 return MorePopover; 9701 }(DateComponent)); 9702 9703 var MoreLinkRoot = /** @class */ (function (_super) { 9704 __extends(MoreLinkRoot, _super); 9705 function MoreLinkRoot() { 9706 var _this = _super !== null && _super.apply(this, arguments) || this; 9707 _this.linkElRef = createRef(); 9708 _this.state = { 9709 isPopoverOpen: false, 9710 popoverId: getUniqueDomId(), 9711 }; 9712 _this.handleClick = function (ev) { 9713 var _a = _this, props = _a.props, context = _a.context; 9714 var moreLinkClick = context.options.moreLinkClick; 9715 var date = computeRange(props).start; 9716 function buildPublicSeg(seg) { 9717 var _a = seg.eventRange, def = _a.def, instance = _a.instance, range = _a.range; 9718 return { 9719 event: new EventApi(context, def, instance), 9720 start: context.dateEnv.toDate(range.start), 9721 end: context.dateEnv.toDate(range.end), 9722 isStart: seg.isStart, 9723 isEnd: seg.isEnd, 9724 }; 9725 } 9726 if (typeof moreLinkClick === 'function') { 9727 moreLinkClick = moreLinkClick({ 9728 date: date, 9729 allDay: Boolean(props.allDayDate), 9730 allSegs: props.allSegs.map(buildPublicSeg), 9731 hiddenSegs: props.hiddenSegs.map(buildPublicSeg), 9732 jsEvent: ev, 9733 view: context.viewApi, 9734 }); 9735 } 9736 if (!moreLinkClick || moreLinkClick === 'popover') { 9737 _this.setState({ isPopoverOpen: true });
9738 } 9739 else if (typeof moreLinkClick === 'string') { // a view name 9740 context.calendarApi.zoomTo(date, moreLinkClick); 9741 } 9742 }; 9743 _this.handlePopoverClose = function () { 9744 _this.setState({ isPopoverOpen: false }); 9745 }; 9746 return _this; 9747 } 9748 MoreLinkRoot.prototype.render = function () { 9749 var _this = this; 9750 var _a = this, props = _a.props, state = _a.state; 9751 return (createElement(ViewContextType.Consumer, null, function (context) { 9752 var viewApi = context.viewApi, options = context.options, calendarApi = context.calendarApi; 9753 var moreLinkText = options.moreLinkText; 9754 var moreCnt = props.moreCnt; 9755 var range = computeRange(props); 9756 var text = typeof moreLinkText === 'function' // TODO: eventually use formatWithOrdinals 9757 ? moreLinkText.call(calendarApi, moreCnt) 9758 : "+" + moreCnt + " " + moreLinkText; 9759 var title = formatWithOrdinals(options.moreLinkHint, [moreCnt], text); 9760 var hookProps = { 9761 num: moreCnt, 9762 shortText: "+" + moreCnt, 9763 text: text, 9764 view: viewApi, 9765 }; 9766 return (createElement(Fragment, null, 9767 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 : ''); })), 9768 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())))); 9769 })); 9770 }; 9771 MoreLinkRoot.prototype.componentDidMount = function () { 9772 this.updateParentEl(); 9773 }; 9774 MoreLinkRoot.prototype.componentDidUpdate = function () { 9775 this.updateParentEl(); 9776 }; 9777 MoreLinkRoot.prototype.updateParentEl = function () { 9778 if (this.linkElRef.current) { 9779 this.parentEl = elementClosest(this.linkElRef.current, '.fc-view-harness'); 9780 } 9781 }; 9782 return MoreLinkRoot; 9783 }(BaseComponent)); 9784 function renderMoreLinkInner$1(props) { 9785 return props.text; 9786 } 9787 function computeRange(props) { 9788 if (props.allDayDate) { 9789 return { 9790 start: props.allDayDate, 9791 end: addDays(props.allDayDate, 1), 9792 }; 9793 } 9794 var hiddenSegs = props.hiddenSegs; 9795 return { 9796 start: computeEarliestSegStart(hiddenSegs), 9797 end: computeLatestSegEnd(hiddenSegs), 9798 }; 9799 } 9800 function computeEarliestSegStart(segs) { 9801 return segs.reduce(pickEarliestStart).eventRange.range.start; 9802 } 9803 function pickEarliestStart(seg0, seg1) { 9804 return seg0.eventRange.range.start < seg1.eventRange.range.start ? seg0 : seg1; 9805 } 9806 function computeLatestSegEnd(segs) { 9807 return segs.reduce(pickLatestEnd).eventRange.range.end; 9808 } 9809 function pickLatestEnd(seg0, seg1) { 9810 return seg0.eventRange.range.end > seg1.eventRange.range.end ? seg0 : seg1; 9811 } 9812 9813 // exports 9814 // -------------------------------------------------------------------------------------------------- 9815 var version = '5.11.3'; // important to type it, so .d.ts has generic string 9816 9817 var Calendar = /** @class */ (function (_super) { 9818 __extends(Calendar, _super); 9819 function Calendar(el, optionOverrides) { 9820 if (optionOverrides === void 0) { optionOverrides = {}; } 9821 var _this = _super.call(this) || this; 9822 _this.isRendering = false; 9823 _this.isRendered = false; 9824 _this.currentClassNames = []; 9825 _this.customContentRenderId = 0; // will affect custom generated classNames? 9826 _this.handleAction = function (action) {
9827 // actions we know we want to render immediately 9828 switch (action.type) { 9829 case 'SET_EVENT_DRAG': 9830 case 'SET_EVENT_RESIZE': 9831 _this.renderRunner.tryDrain(); 9832 } 9833 }; 9834 _this.handleData = function (data) { 9835 _this.currentData = data; 9836 _this.renderRunner.request(data.calendarOptions.rerenderDelay); 9837 }; 9838 _this.handleRenderRequest = function () { 9839 if (_this.isRendering) { 9840 _this.isRendered = true; 9841 var currentData_1 = _this.currentData; 9842 flushSync(function () { 9843 render(createElement(CalendarRoot, { options: currentData_1.calendarOptions, theme: currentData_1.theme, emitter: currentData_1.emitter }, function (classNames, height, isHeightAuto, forPrint) { 9844 _this.setClassNames(classNames); 9845 _this.setHeight(height); 9846 return (createElement(CustomContentRenderContext.Provider, { value: _this.customContentRenderId }, 9847 createElement(CalendarContent, __assign({ isHeightAuto: isHeightAuto, forPrint: forPrint }, currentData_1)))); 9848 }), _this.el); 9849 }); 9850 } 9851 else if (_this.isRendered) { 9852 _this.isRendered = false; 9853 unmountComponentAtNode(_this.el); 9854 _this.setClassNames([]); 9855 _this.setHeight(''); 9856 } 9857 }; 9858 _this.el = el; 9859 _this.renderRunner = new DelayedRunner(_this.handleRenderRequest); 9860 new CalendarDataManager({ 9861 optionOverrides: optionOverrides, 9862 calendarApi: _this, 9863 onAction: _this.handleAction, 9864 onData: _this.handleData, 9865 }); 9866 return _this; 9867 } 9868 Object.defineProperty(Calendar.prototype, "view", { 9869 get: function () { return this.currentData.viewApi; } // for public API 9870 , 9871 enumerable: false, 9872 configurable: true 9873 }); 9874 Calendar.prototype.render = function () { 9875 var wasRendering = this.isRendering; 9876 if (!wasRendering) { 9877 this.isRendering = true; 9878 } 9879 else { 9880 this.customContentRenderId += 1; 9881 } 9882 this.renderRunner.request(); 9883 if (wasRendering) { 9884 this.updateSize(); 9885 } 9886 }; 9887 Calendar.prototype.destroy = function () { 9888 if (this.isRendering) { 9889 this.isRendering = false; 9890 this.renderRunner.request(); 9891 } 9892 }; 9893 Calendar.prototype.updateSize = function () { 9894 var _this = this; 9895 flushSync(function () { 9896 _super.prototype.updateSize.call(_this); 9897 }); 9898 }; 9899 Calendar.prototype.batchRendering = function (func) { 9900 this.renderRunner.pause('batchRendering'); 9901 func(); 9902 this.renderRunner.resume('batchRendering'); 9903 }; 9904 Calendar.prototype.pauseRendering = function () { 9905 this.renderRunner.pause('pauseRendering'); 9906 }; 9907 Calendar.prototype.resumeRendering = function () { 9908 this.renderRunner.resume('pauseRendering', true); 9909 }; 9910 Calendar.prototype.resetOptions = function (optionOverrides, append) { 9911 this.currentDataManager.resetOptions(optionOverrides, append); 9912 }; 9913 Calendar.prototype.setClassNames = function (classNames) { 9914 if (!isArraysEqual(classNames, this.currentClassNames)) { 9915 var classList = this.el.classList; 9916 for (var _i = 0, _a = this.currentClassNames; _i < _a.length; _i++) { 9917 var className = _a[_i]; 9918 classList.remove(className); 9919 } 9920 for (var _b = 0, classNames_1 = classNames; _b < classNames_1.length; _b++) { 9921 var className = classNames_1[_b]; 9922 classList.add(className); 9923 } 9924 this.currentClassNames = classNames; 9925 } 9926 }; 9927 Calendar.prototype.setHeight = function (height) { 9928 applyStyleProp(this.el, 'height', height); 9929 }; 9930 return Calendar; 9931 }(CalendarApi)); 9932 9933 config.touchMouseIgnoreWait = 500; 9934 var ignoreMouseDepth = 0; 9935 var listenerCnt = 0; 9936 var isWindowTouchMoveCancelled = false; 9937 /* 9938 Uses a "pointer" abstraction, which monitors UI events for both mouse and touch. 9939 Tracks when the pointer "drags" on a certain element, meaning down+move+up. 9940 9941 Also, tracks if there was touch-scrolling. 9942 Also, can prevent touch-scrolling from happening. 9943 Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement. 9944 9945 emits: 9946 - pointerdown 9947 - pointermove 9948 - pointerup 9949 */ 9950 var PointerDragging = /** @class */ (function () { 9951 function PointerDragging(containerEl) { 9952 var _this = this; 9953 this.subjectEl = null; 9954 // options that can be directly assigned by caller 9955 this.selector = ''; // will cause subjectEl in all emitted events to be this element 9956 this.handleSelector = ''; 9957 this.shouldIgnoreMove = false; 9958 this.shouldWatchScroll = true; // for simulating pointermove on scroll 9959 // internal states 9960 this.isDragging = false; 9961 this.isTouchDragging = false; 9962 this.wasTouchScroll = false; 9963 // Mouse 9964 // ---------------------------------------------------------------------------------------------------- 9965 this.handleMouseDown = function (ev) { 9966 if (!_this.shouldIgnoreMouse() && 9967 isPrimaryMouseButton(ev) && 9968 _this.tryStart(ev)) { 9969 var pev = _this.createEventFromMouse(ev, true); 9970 _this.emitter.trigger('pointerdown', pev); 9971 _this.initScrollWatch(pev); 9972 if (!_this.shouldIgnoreMove) { 9973 document.addEventListener('mousemove', _this.handleMouseMove); 9974 } 9975 document.addEventListener('mouseup', _this.handleMouseUp); 9976 } 9977 }; 9978 this.handleMouseMove = function (ev) { 9979 var pev = _this.createEventFromMouse(ev); 9980 _this.recordCoords(pev); 9981 _this.emitter.trigger('pointermove', pev); 9982 }; 9983 this.handleMouseUp = function (ev) { 9984 document.removeEventListener('mousemove', _this.handleMouseMove); 9985 document.removeEventListener('mouseup', _this.handleMouseUp); 9986 _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev)); 9987 _this.cleanup(); // call last so that pointerup has access to props 9988 }; 9989 // Touch 9990 // ---------------------------------------------------------------------------------------------------- 9991 this.handleTouchStart = function (ev) { 9992 if (_this.tryStart(ev)) { 9993 _this.isTouchDragging = true; 9994 var pev = _this.createEventFromTouch(ev, true); 9995 _this.emitter.trigger('pointerdown', pev); 9996 _this.initScrollWatch(pev); 9997 // unlike mouse, need to attach to target, not document 9998 // https://stackoverflow.com/a/45760014 9999 var targetEl = ev.target; 10000 if (!_this.shouldIgnoreMove) { 10001 targetEl.addEventListener('touchmove', _this.handleTouchMove); 10002 } 10003 targetEl.addEventListener('touchend', _this.handleTouchEnd); 10004 targetEl.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end 10005 // attach a handler to get called when ANY scroll action happens on the page. 10006 // this was impossible to do with normal on/off because 'scroll' doesn't bubble. 10007 // http://stackoverflow.com/a/32954565/96342 10008 window.addEventListener('scroll', _this.handleTouchScroll, true); 10009 } 10010 }; 10011 this.handleTouchMove = function (ev) { 10012 var pev = _this.createEventFromTouch(ev); 10013 _this.recordCoords(pev); 10014 _this.emitter.trigger('pointermove', pev); 10015 }; 10016 this.handleTouchEnd = function (ev) { 10017 if (_this.isDragging) { // done to guard against touchend followed by touchcancel 10018 var targetEl = ev.target; 10019 targetEl.removeEventListener('touchmove', _this.handleTouchMove); 10020 targetEl.removeEventListener('touchend', _this.handleTouchEnd); 10021 targetEl.removeEventListener('touchcancel', _this.handleTouchEnd); 10022 window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true 10023 _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev)); 10024 _this.cleanup(); // call last so that pointerup has access to props 10025 _this.isTouchDragging = false; 10026 startIgnoringMouse(); 10027 } 10028 }; 10029 this.handleTouchScroll = function () { 10030 _this.wasTouchScroll = true; 10031 }; 10032 this.handleScroll = function (ev) { 10033 if (!_this.shouldIgnoreMove) { 10034 var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX; 10035 var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY; 10036 _this.emitter.trigger('pointermove', { 10037 origEvent: ev, 10038 isTouch: _this.isTouchDragging, 10039 subjectEl: _this.subjectEl, 10040 pageX: pageX, 10041 pageY: pageY, 10042 deltaX: pageX - _this.origPageX, 10043 deltaY: pageY - _this.origPageY, 10044 }); 10045 } 10046 }; 10047 this.containerEl = containerEl; 10048 this.emitter = new Emitter(); 10049 containerEl.addEventListener('mousedown', this.handleMouseDown);
10050 containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true }); 10051 listenerCreated(); 10052 } 10053 PointerDragging.prototype.destroy = function () { 10054 this.containerEl.removeEventListener('mousedown', this.handleMouseDown); 10055 this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true }); 10056 listenerDestroyed(); 10057 }; 10058 PointerDragging.prototype.tryStart = function (ev) { 10059 var subjectEl = this.querySubjectEl(ev); 10060 var downEl = ev.target; 10061 if (subjectEl && 10062 (!this.handleSelector || elementClosest(downEl, this.handleSelector))) { 10063 this.subjectEl = subjectEl; 10064 this.isDragging = true; // do this first so cancelTouchScroll will work 10065 this.wasTouchScroll = false; 10066 return true; 10067 } 10068 return false; 10069 }; 10070 PointerDragging.prototype.cleanup = function () { 10071 isWindowTouchMoveCancelled = false; 10072 this.isDragging = false; 10073 this.subjectEl = null; 10074 // keep wasTouchScroll around for later access 10075 this.destroyScrollWatch(); 10076 }; 10077 PointerDragging.prototype.querySubjectEl = function (ev) { 10078 if (this.selector) { 10079 return elementClosest(ev.target, this.selector); 10080 } 10081 return this.containerEl; 10082 }; 10083 PointerDragging.prototype.shouldIgnoreMouse = function () { 10084 return ignoreMouseDepth || this.isTouchDragging; 10085 }; 10086 // can be called by user of this class, to cancel touch-based scrolling for the current drag 10087 PointerDragging.prototype.cancelTouchScroll = function () { 10088 if (this.isDragging) { 10089 isWindowTouchMoveCancelled = true; 10090 } 10091 }; 10092 // Scrolling that simulates pointermoves 10093 // ---------------------------------------------------------------------------------------------------- 10094 PointerDragging.prototype.initScrollWatch = function (ev) { 10095 if (this.shouldWatchScroll) { 10096 this.recordCoords(ev); 10097 window.addEventListener('scroll', this.handleScroll, true); // useCapture=true 10098 } 10099 }; 10100 PointerDragging.prototype.recordCoords = function (ev) { 10101 if (this.shouldWatchScroll) { 10102 this.prevPageX = ev.pageX; 10103 this.prevPageY = ev.pageY; 10104 this.prevScrollX = window.pageXOffset; 10105 this.prevScrollY = window.pageYOffset; 10106 } 10107 }; 10108 PointerDragging.prototype.destroyScrollWatch = function () { 10109 if (this.shouldWatchScroll) { 10110 window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true 10111 } 10112 }; 10113 // Event Normalization 10114 // ---------------------------------------------------------------------------------------------------- 10115 PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) { 10116 var deltaX = 0; 10117 var deltaY = 0; 10118 // TODO: repeat code 10119 if (isFirst) { 10120 this.origPageX = ev.pageX; 10121 this.origPageY = ev.pageY; 10122 } 10123 else { 10124 deltaX = ev.pageX - this.origPageX; 10125 deltaY = ev.pageY - this.origPageY; 10126 } 10127 return { 10128 origEvent: ev, 10129 isTouch: false, 10130 subjectEl: this.subjectEl, 10131 pageX: ev.pageX, 10132 pageY: ev.pageY, 10133 deltaX: deltaX, 10134 deltaY: deltaY, 10135 }; 10136 }; 10137 PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) { 10138 var touches = ev.touches; 10139 var pageX; 10140 var pageY; 10141 var deltaX = 0; 10142 var deltaY = 0; 10143 // if touch coords available, prefer, 10144 // because FF would give bad ev.pageX ev.pageY 10145 if (touches && touches.length) { 10146 pageX = touches[0].pageX; 10147 pageY = touches[0].pageY; 10148 } 10149 else { 10150 pageX = ev.pageX; 10151 pageY = ev.pageY; 10152 } 10153 // TODO: repeat code 10154 if (isFirst) { 10155 this.origPageX = pageX; 10156 this.origPageY = pageY; 10157 } 10158 else { 10159 deltaX = pageX - this.origPageX; 10160 deltaY = pageY - this.origPageY; 10161 } 10162 return { 10163 origEvent: ev, 10164 isTouch: true, 10165 subjectEl: this.subjectEl, 10166 pageX: pageX, 10167 pageY: pageY, 10168 deltaX: deltaX, 10169 deltaY: deltaY, 10170 }; 10171 }; 10172 return PointerDragging; 10173 }());
10174 // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac) 10175 function isPrimaryMouseButton(ev) { 10176 return ev.button === 0 && !ev.ctrlKey; 10177 } 10178 // Ignoring fake mouse events generated by touch 10179 // ---------------------------------------------------------------------------------------------------- 10180 function startIgnoringMouse() { 10181 ignoreMouseDepth += 1; 10182 setTimeout(function () { 10183 ignoreMouseDepth -= 1; 10184 }, config.touchMouseIgnoreWait); 10185 } 10186 // We want to attach touchmove as early as possible for Safari 10187 // ---------------------------------------------------------------------------------------------------- 10188 function listenerCreated() { 10189 listenerCnt += 1; 10190 if (listenerCnt === 1) { 10191 window.addEventListener('touchmove', onWindowTouchMove, { passive: false }); 10192 } 10193 } 10194 function listenerDestroyed() { 10195 listenerCnt -= 1; 10196 if (!listenerCnt) { 10197 window.removeEventListener('touchmove', onWindowTouchMove, { passive: false }); 10198 } 10199 } 10200 function onWindowTouchMove(ev) { 10201 if (isWindowTouchMoveCancelled) { 10202 ev.preventDefault(); 10203 } 10204 } 10205 10206 /* 10207 An effect in which an element follows the movement of a pointer across the screen. 10208 The moving element is a clone of some other element. 10209 Must call start + handleMove + stop. 10210 */ 10211 var ElementMirror = /** @class */ (function () { 10212 function ElementMirror() { 10213 this.isVisible = false; // must be explicitly enabled 10214 this.sourceEl = null; 10215 this.mirrorEl = null; 10216 this.sourceElRect = null; // screen coords relative to viewport 10217 // options that can be set directly by caller 10218 this.parentNode = document.body; // HIGHLY SUGGESTED to set this to sidestep ShadowDOM issues 10219 this.zIndex = 9999; 10220 this.revertDuration = 0; 10221 } 10222 ElementMirror.prototype.start = function (sourceEl, pageX, pageY) { 10223 this.sourceEl = sourceEl; 10224 this.sourceElRect = this.sourceEl.getBoundingClientRect(); 10225 this.origScreenX = pageX - window.pageXOffset; 10226 this.origScreenY = pageY - window.pageYOffset; 10227 this.deltaX = 0; 10228 this.deltaY = 0; 10229 this.updateElPosition(); 10230 }; 10231 ElementMirror.prototype.handleMove = function (pageX, pageY) { 10232 this.deltaX = (pageX - window.pageXOffset) - this.origScreenX; 10233 this.deltaY = (pageY - window.pageYOffset) - this.origScreenY; 10234 this.updateElPosition(); 10235 }; 10236 // can be called before start 10237 ElementMirror.prototype.setIsVisible = function (bool) { 10238 if (bool) { 10239 if (!this.isVisible) { 10240 if (this.mirrorEl) { 10241 this.mirrorEl.style.display = ''; 10242 } 10243 this.isVisible = bool; // needs to happen before updateElPosition 10244 this.updateElPosition(); // because was not updating the position while invisible 10245 } 10246 } 10247 else if (this.isVisible) { 10248 if (this.mirrorEl) { 10249 this.mirrorEl.style.display = 'none'; 10250 } 10251 this.isVisible = bool; 10252 } 10253 }; 10254 // always async 10255 ElementMirror.prototype.stop = function (needsRevertAnimation, callback) { 10256 var _this = this; 10257 var done = function () { 10258 _this.cleanup(); 10259 callback(); 10260 }; 10261 if (needsRevertAnimation && 10262 this.mirrorEl && 10263 this.isVisible && 10264 this.revertDuration && // if 0, transition won't work 10265 (this.deltaX || this.deltaY) // if same coords, transition won't work 10266 ) { 10267 this.doRevertAnimation(done, this.revertDuration); 10268 } 10269 else { 10270 setTimeout(done, 0); 10271 } 10272 }; 10273 ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) { 10274 var mirrorEl = this.mirrorEl; 10275 var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened 10276 mirrorEl.style.transition = 10277 'top ' + revertDuration + 'ms,' + 10278 'left ' + revertDuration + 'ms'; 10279 applyStyle(mirrorEl, { 10280 left: finalSourceElRect.left, 10281 top: finalSourceElRect.top, 10282 }); 10283 whenTransitionDone(mirrorEl, function () { 10284 mirrorEl.style.transition = ''; 10285 callback(); 10286 }); 10287 }; 10288 ElementMirror.prototype.cleanup = function () { 10289 if (this.mirrorEl) { 10290 removeElement(this.mirrorEl); 10291 this.mirrorEl = null; 10292 } 10293 this.sourceEl = null; 10294 }; 10295 ElementMirror.prototype.updateElPosition = function () { 10296 if (this.sourceEl && this.isVisible) { 10297 applyStyle(this.getMirrorEl(), { 10298 left: this.sourceElRect.left + this.deltaX, 10299 top: this.sourceElRect.top + this.deltaY, 10300 }); 10301 } 10302 }; 10303 ElementMirror.prototype.getMirrorEl = function () { 10304 var sourceElRect = this.sourceElRect; 10305 var mirrorEl = this.mirrorEl; 10306 if (!mirrorEl) { 10307 mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true 10308 // we don't want long taps or any mouse interaction causing selection/menus. 10309 // would use preventSelection(), but that prevents selectstart, causing problems. 10310 mirrorEl.classList.add('fc-unselectable'); 10311 mirrorEl.classList.add('fc-event-dragging'); 10312 applyStyle(mirrorEl, { 10313 position: 'fixed', 10314 zIndex: this.zIndex, 10315 visibility: '', 10316 boxSizing: 'border-box', 10317 width: sourceElRect.right - sourceElRect.left, 10318 height: sourceElRect.bottom - sourceElRect.top, 10319 right: 'auto', 10320 bottom: 'auto', 10321 margin: 0, 10322 }); 10323 this.parentNode.appendChild(mirrorEl); 10324 } 10325 return mirrorEl; 10326 }; 10327 return ElementMirror; 10328 }()); 10329 10330 /* 10331 Is a cache for a given element's scroll information (all the info that ScrollController stores) 10332 in addition the "client rectangle" of the element.. the area within the scrollbars. 10333 10334 The cache can be in one of two modes: 10335 - doesListening:false - ignores when the container is scrolled by someone else 10336 - doesListening:true - watch for scrolling and update the cache 10337 */ 10338 var ScrollGeomCache = /** @class */ (function (_super) { 10339 __extends(ScrollGeomCache, _super); 10340 function ScrollGeomCache(scrollController, doesListening) { 10341 var _this = _super.call(this) || this; 10342 _this.handleScroll = function () { 10343 _this.scrollTop = _this.scrollController.getScrollTop(); 10344 _this.scrollLeft = _this.scrollController.getScrollLeft(); 10345 _this.handleScrollChange(); 10346 };
10347 _this.scrollController = scrollController; 10348 _this.doesListening = doesListening; 10349 _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop(); 10350 _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft(); 10351 _this.scrollWidth = scrollController.getScrollWidth(); 10352 _this.scrollHeight = scrollController.getScrollHeight(); 10353 _this.clientWidth = scrollController.getClientWidth(); 10354 _this.clientHeight = scrollController.getClientHeight(); 10355 _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values 10356 if (_this.doesListening) { 10357 _this.getEventTarget().addEventListener('scroll', _this.handleScroll); 10358 } 10359 return _this; 10360 } 10361 ScrollGeomCache.prototype.destroy = function () { 10362 if (this.doesListening) { 10363 this.getEventTarget().removeEventListener('scroll', this.handleScroll); 10364 } 10365 }; 10366 ScrollGeomCache.prototype.getScrollTop = function () { 10367 return this.scrollTop; 10368 }; 10369 ScrollGeomCache.prototype.getScrollLeft = function () { 10370 return this.scrollLeft; 10371 }; 10372 ScrollGeomCache.prototype.setScrollTop = function (top) { 10373 this.scrollController.setScrollTop(top); 10374 if (!this.doesListening) { 10375 // we are not relying on the element to normalize out-of-bounds scroll values 10376 // so we need to sanitize ourselves 10377 this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0); 10378 this.handleScrollChange(); 10379 } 10380 }; 10381 ScrollGeomCache.prototype.setScrollLeft = function (top) { 10382 this.scrollController.setScrollLeft(top); 10383 if (!this.doesListening) { 10384 // we are not relying on the element to normalize out-of-bounds scroll values 10385 // so we need to sanitize ourselves 10386 this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0); 10387 this.handleScrollChange(); 10388 } 10389 }; 10390 ScrollGeomCache.prototype.getClientWidth = function () { 10391 return this.clientWidth; 10392 }; 10393 ScrollGeomCache.prototype.getClientHeight = function () { 10394 return this.clientHeight; 10395 }; 10396 ScrollGeomCache.prototype.getScrollWidth = function () { 10397 return this.scrollWidth; 10398 }; 10399 ScrollGeomCache.prototype.getScrollHeight = function () { 10400 return this.scrollHeight; 10401 }; 10402 ScrollGeomCache.prototype.handleScrollChange = function () { 10403 }; 10404 return ScrollGeomCache; 10405 }(ScrollController)); 10406 10407 var ElementScrollGeomCache = /** @class */ (function (_super) { 10408 __extends(ElementScrollGeomCache, _super); 10409 function ElementScrollGeomCache(el, doesListening) { 10410 return _super.call(this, new ElementScrollController(el), doesListening) || this; 10411 } 10412 ElementScrollGeomCache.prototype.getEventTarget = function () { 10413 return this.scrollController.el; 10414 }; 10415 ElementScrollGeomCache.prototype.computeClientRect = function () { 10416 return computeInnerRect(this.scrollController.el); 10417 }; 10418 return ElementScrollGeomCache; 10419 }(ScrollGeomCache)); 10420 10421 var WindowScrollGeomCache = /** @class */ (function (_super) { 10422 __extends(WindowScrollGeomCache, _super); 10423 function WindowScrollGeomCache(doesListening) { 10424 return _super.call(this, new WindowScrollController(), doesListening) || this; 10425 } 10426 WindowScrollGeomCache.prototype.getEventTarget = function () { 10427 return window; 10428 }; 10429 WindowScrollGeomCache.prototype.computeClientRect = function () { 10430 return { 10431 left: this.scrollLeft, 10432 right: this.scrollLeft + this.clientWidth, 10433 top: this.scrollTop, 10434 bottom: this.scrollTop + this.clientHeight, 10435 }; 10436 }; 10437 // the window is the only scroll object that changes it's rectangle relative 10438 // to the document's topleft as it scrolls 10439 WindowScrollGeomCache.prototype.handleScrollChange = function () { 10440 this.clientRect = this.computeClientRect(); 10441 }; 10442 return WindowScrollGeomCache; 10443 }(ScrollGeomCache)); 10444 10445 // If available we are using native "performance" API instead of "Date" 10446 // Read more about it on MDN: 10447 // https://developer.mozilla.org/en-US/docs/Web/API/Performance 10448 var getTime = typeof performance === 'function' ? performance.now : Date.now; 10449 /* 10450 For a pointer interaction, automatically scrolls certain scroll containers when the pointer 10451 approaches the edge. 10452 10453 The caller must call start + handleMove + stop. 10454 */ 10455 var AutoScroller = /** @class */ (function () { 10456 function AutoScroller() { 10457 var _this = this; 10458 // options that can be set by caller 10459 this.isEnabled = true; 10460 this.scrollQuery = [window, '.fc-scroller']; 10461 this.edgeThreshold = 50; // pixels 10462 this.maxVelocity = 300; // pixels per second 10463 // internal state 10464 this.pointerScreenX = null; 10465 this.pointerScreenY = null; 10466 this.isAnimating = false; 10467 this.scrollCaches = null; 10468 // protect against the initial pointerdown being too close to an edge and starting the scroll 10469 this.everMovedUp = false; 10470 this.everMovedDown = false; 10471 this.everMovedLeft = false; 10472 this.everMovedRight = false; 10473 this.animate = function () { 10474 if (_this.isAnimating) { // wasn't cancelled between animation calls 10475 var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset); 10476 if (edge) { 10477 var now = getTime(); 10478 _this.handleSide(edge, (now - _this.msSinceRequest) / 1000); 10479 _this.requestAnimation(now); 10480 } 10481 else { 10482 _this.isAnimating = false; // will stop animation 10483 } 10484 } 10485 }; 10486 } 10487 AutoScroller.prototype.start = function (pageX, pageY, scrollStartEl) { 10488 if (this.isEnabled) { 10489 this.scrollCaches = this.buildCaches(scrollStartEl); 10490 this.pointerScreenX = null; 10491 this.pointerScreenY = null; 10492 this.everMovedUp = false; 10493 this.everMovedDown = false; 10494 this.everMovedLeft = false; 10495 this.everMovedRight = false; 10496 this.handleMove(pageX, pageY); 10497 } 10498 }; 10499 AutoScroller.prototype.handleMove = function (pageX, pageY) { 10500 if (this.isEnabled) { 10501 var pointerScreenX = pageX - window.pageXOffset; 10502 var pointerScreenY = pageY - window.pageYOffset; 10503 var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY; 10504 var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX; 10505 if (yDelta < 0) { 10506 this.everMovedUp = true; 10507 } 10508 else if (yDelta > 0) { 10509 this.everMovedDown = true; 10510 } 10511 if (xDelta < 0) { 10512 this.everMovedLeft = true; 10513 } 10514 else if (xDelta > 0) { 10515 this.everMovedRight = true; 10516 } 10517 this.pointerScreenX = pointerScreenX; 10518 this.pointerScreenY = pointerScreenY; 10519 if (!this.isAnimating) { 10520 this.isAnimating = true; 10521 this.requestAnimation(getTime()); 10522 } 10523 } 10524 }; 10525 AutoScroller.prototype.stop = function () { 10526 if (this.isEnabled) { 10527 this.isAnimating = false; // will stop animation 10528 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10529 var scrollCache = _a[_i]; 10530 scrollCache.destroy(); 10531 } 10532 this.scrollCaches = null; 10533 } 10534 }; 10535 AutoScroller.prototype.requestAnimation = function (now) { 10536 this.msSinceRequest = now; 10537 requestAnimationFrame(this.animate); 10538 }; 10539 AutoScroller.prototype.handleSide = function (edge, seconds) { 10540 var scrollCache = edge.scrollCache; 10541 var edgeThreshold = this.edgeThreshold; 10542 var invDistance = edgeThreshold - edge.distance; 10543 var velocity = // the closer to the edge, the faster we scroll 10544 ((invDistance * invDistance) / (edgeThreshold * edgeThreshold)) * // quadratic 10545 this.maxVelocity * seconds; 10546 var sign = 1; 10547 switch (edge.name) { 10548 case 'left': 10549 sign = -1; 10550 // falls through 10551 case 'right': 10552 scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign); 10553 break; 10554 case 'top': 10555 sign = -1; 10556 // falls through 10557 case 'bottom': 10558 scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign); 10559 break; 10560 } 10561 }; 10562 // left/top are relative to document topleft 10563 AutoScroller.prototype.computeBestEdge = function (left, top) { 10564 var edgeThreshold = this.edgeThreshold; 10565 var bestSide = null; 10566 var scrollCaches = this.scrollCaches || []; 10567 for (var _i = 0, scrollCaches_1 = scrollCaches; _i < scrollCaches_1.length; _i++) { 10568 var scrollCache = scrollCaches_1[_i]; 10569 var rect = scrollCache.clientRect; 10570 var leftDist = left - rect.left; 10571 var rightDist = rect.right - left; 10572 var topDist = top - rect.top; 10573 var bottomDist = rect.bottom - top; 10574 // completely within the rect? 10575 if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) { 10576 if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() && 10577 (!bestSide || bestSide.distance > topDist)) { 10578 bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist }; 10579 } 10580 if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() && 10581 (!bestSide || bestSide.distance > bottomDist)) { 10582 bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist }; 10583 } 10584 if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() && 10585 (!bestSide || bestSide.distance > leftDist)) { 10586 bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist }; 10587 } 10588 if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() && 10589 (!bestSide || bestSide.distance > rightDist)) { 10590 bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist }; 10591 } 10592 } 10593 } 10594 return bestSide; 10595 }; 10596 AutoScroller.prototype.buildCaches = function (scrollStartEl) { 10597 return this.queryScrollEls(scrollStartEl).map(function (el) { 10598 if (el === window) { 10599 return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls 10600 } 10601 return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls 10602 }); 10603 }; 10604 AutoScroller.prototype.queryScrollEls = function (scrollStartEl) { 10605 var els = []; 10606 for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) { 10607 var query = _a[_i]; 10608 if (typeof query === 'object') { 10609 els.push(query); 10610 } 10611 else { 10612 els.push.apply(els, Array.prototype.slice.call(getElRoot(scrollStartEl).querySelectorAll(query))); 10613 } 10614 } 10615 return els; 10616 }; 10617 return AutoScroller; 10618 }()); 10619 10620 /* 10621 Monitors dragging on an element. Has a number of high-level features: 10622 - minimum distance required before dragging 10623 - minimum wait time ("delay") before dragging 10624 - a mirror element that follows the pointer 10625 */ 10626 var FeaturefulElementDragging = /** @class */ (function (_super) { 10627 __extends(FeaturefulElementDragging, _super); 10628 function FeaturefulElementDragging(containerEl, selector) { 10629 var _this = _super.call(this, containerEl) || this; 10630 _this.containerEl = containerEl; 10631 // options that can be directly set by caller 10632 // the caller can also set the PointerDragging's options as well 10633 _this.delay = null; 10634 _this.minDistance = 0; 10635 _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag 10636 _this.mirrorNeedsRevert = false; 10637 _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup 10638 _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation 10639 _this.isDelayEnded = false; 10640 _this.isDistanceSurpassed = false; 10641 _this.delayTimeoutId = null; 10642 _this.onPointerDown = function (ev) { 10643 if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going 10644 _this.isInteracting = true; 10645 _this.isDelayEnded = false; 10646 _this.isDistanceSurpassed = false; 10647 preventSelection(document.body); 10648 preventContextMenu(document.body); 10649 // prevent links from being visited if there's an eventual drag. 10650 // also prevents selection in older browsers (maybe?). 10651 // not necessary for touch, besides, browser would complain about passiveness. 10652 if (!ev.isTouch) { 10653 ev.origEvent.preventDefault(); 10654 } 10655 _this.emitter.trigger('pointerdown', ev); 10656 if (_this.isInteracting && // not destroyed via pointerdown handler 10657 !_this.pointer.shouldIgnoreMove) { 10658 // actions related to initiating dragstart+dragmove+dragend... 10659 _this.mirror.setIsVisible(false); // reset. caller must set-visible 10660 _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down 10661 _this.startDelay(ev); 10662 if (!_this.minDistance) { 10663 _this.handleDistanceSurpassed(ev); 10664 } 10665 } 10666 } 10667 }; 10668 _this.onPointerMove = function (ev) { 10669 if (_this.isInteracting) { 10670 _this.emitter.trigger('pointermove', ev); 10671 if (!_this.isDistanceSurpassed) { 10672 var minDistance = _this.minDistance; 10673 var distanceSq = void 0; // current distance from the origin, squared 10674 var deltaX = ev.deltaX, deltaY = ev.deltaY; 10675 distanceSq = deltaX * deltaX + deltaY * deltaY; 10676 if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem 10677
10677 _this.handleDistanceSurpassed(ev); 10678 } 10679 } 10680 if (_this.isDragging) { 10681 // a real pointer move? (not one simulated by scrolling) 10682 if (ev.origEvent.type !== 'scroll') { 10683 _this.mirror.handleMove(ev.pageX, ev.pageY); 10684 _this.autoScroller.handleMove(ev.pageX, ev.pageY); 10685 } 10686 _this.emitter.trigger('dragmove', ev); 10687 } 10688 } 10689 }; 10690 _this.onPointerUp = function (ev) { 10691 if (_this.isInteracting) { 10692 _this.isInteracting = false; 10693 allowSelection(document.body); 10694 allowContextMenu(document.body); 10695 _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert 10696 if (_this.isDragging) { 10697 _this.autoScroller.stop(); 10698 _this.tryStopDrag(ev); // which will stop the mirror 10699 } 10700 if (_this.delayTimeoutId) { 10701 clearTimeout(_this.delayTimeoutId); 10702 _this.delayTimeoutId = null; 10703 } 10704 } 10705 }; 10706 var pointer = _this.pointer = new PointerDragging(containerEl); 10707 pointer.emitter.on('pointerdown', _this.onPointerDown); 10708 pointer.emitter.on('pointermove', _this.onPointerMove); 10709 pointer.emitter.on('pointerup', _this.onPointerUp); 10710 if (selector) { 10711 pointer.selector = selector; 10712 } 10713 _this.mirror = new ElementMirror(); 10714 _this.autoScroller = new AutoScroller(); 10715 return _this; 10716 } 10717 FeaturefulElementDragging.prototype.destroy = function () { 10718 this.pointer.destroy(); 10719 // HACK: simulate a pointer-up to end the current drag
10720 // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire) 10721 this.onPointerUp({}); 10722 }; 10723 FeaturefulElementDragging.prototype.startDelay = function (ev) { 10724 var _this = this; 10725 if (typeof this.delay === 'number') { 10726 this.delayTimeoutId = setTimeout(function () { 10727 _this.delayTimeoutId = null; 10728 _this.handleDelayEnd(ev); 10729 }, this.delay); // not assignable to number! 10730 } 10731 else { 10732 this.handleDelayEnd(ev); 10733 } 10734 }; 10735 FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) { 10736 this.isDelayEnded = true; 10737 this.tryStartDrag(ev); 10738 }; 10739 FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) { 10740 this.isDistanceSurpassed = true; 10741 this.tryStartDrag(ev); 10742 }; 10743 FeaturefulElementDragging.prototype.tryStartDrag = function (ev) { 10744 if (this.isDelayEnded && this.isDistanceSurpassed) { 10745 if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) { 10746 this.isDragging = true; 10747 this.mirrorNeedsRevert = false; 10748 this.autoScroller.start(ev.pageX, ev.pageY, this.containerEl); 10749 this.emitter.trigger('dragstart', ev); 10750 if (this.touchScrollAllowed === false) { 10751 this.pointer.cancelTouchScroll(); 10752 } 10753 } 10754 } 10755 }; 10756 FeaturefulElementDragging.prototype.tryStopDrag = function (ev) { 10757 // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events 10758 // that come from the document to fire beforehand. much more convenient this way. 10759 this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev)); 10760 }; 10761 FeaturefulElementDragging.prototype.stopDrag = function (ev) { 10762 this.isDragging = false; 10763 this.emitter.trigger('dragend', ev); 10764 }; 10765 // fill in the implementations... 10766 FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) { 10767 this.pointer.shouldIgnoreMove = bool; 10768 }; 10769 FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) { 10770 this.mirror.setIsVisible(bool); 10771 }; 10772 FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 10773 this.mirrorNeedsRevert = bool; 10774 }; 10775 FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) { 10776 this.autoScroller.isEnabled = bool; 10777 }; 10778 return FeaturefulElementDragging; 10779 }(ElementDragging)); 10780 10781 /* 10782 When this class is instantiated, it records the offset of an element (relative to the document topleft), 10783 and continues to monitor scrolling, updating the cached coordinates if it needs to. 10784 Does not access the DOM after instantiation, so highly performant. 10785 10786 Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element 10787 and an determine if a given point is inside the combined clipping rectangle. 10788 */ 10789 var OffsetTracker = /** @class */ (function () { 10790 function OffsetTracker(el) { 10791 this.origRect = computeRect(el); 10792 // will work fine for divs that have overflow:hidden 10793 this.scrollCaches = getClippingParents(el).map(function (scrollEl) { return new ElementScrollGeomCache(scrollEl, true); }); 10794 } 10795 OffsetTracker.prototype.destroy = function () { 10796 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10797 var scrollCache = _a[_i]; 10798 scrollCache.destroy(); 10799 } 10800 }; 10801 OffsetTracker.prototype.computeLeft = function () { 10802 var left = this.origRect.left; 10803 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10804 var scrollCache = _a[_i]; 10805 left += scrollCache.origScrollLeft - scrollCache.getScrollLeft(); 10806 } 10807 return left; 10808 }; 10809 OffsetTracker.prototype.computeTop = function () { 10810 var top = this.origRect.top; 10811 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10812 var scrollCache = _a[_i]; 10813 top += scrollCache.origScrollTop - scrollCache.getScrollTop(); 10814 } 10815 return top; 10816 }; 10817 OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) { 10818 var point = { left: pageX, top: pageY }; 10819 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10820 var scrollCache = _a[_i];
10821 if (!isIgnoredClipping(scrollCache.getEventTarget()) && 10822 !pointInsideRect(point, scrollCache.clientRect)) { 10823 return false; 10824 } 10825 } 10826 return true; 10827 }; 10828 return OffsetTracker; 10829 }()); 10830 // certain clipping containers should never constrain interactions, like <html> and <body> 10831 // https://github.com/fullcalendar/fullcalendar/issues/3615 10832 function isIgnoredClipping(node) { 10833 var tagName = node.tagName; 10834 return tagName === 'HTML' || tagName === 'BODY'; 10835 } 10836 10837 /* 10838 Tracks movement over multiple droppable areas (aka "hits") 10839 that exist in one or more DateComponents. 10840 Relies on an existing draggable. 10841 10842 emits: 10843 - pointerdown 10844 - dragstart 10845 - hitchange - fires initially, even if not over a hit 10846 - pointerup 10847 - (hitchange - again, to null, if ended over a hit) 10848 - dragend 10849 */ 10850 var HitDragging = /** @class */ (function () { 10851 function HitDragging(dragging, droppableStore) { 10852 var _this = this; 10853 // options that can be set by caller 10854 this.useSubjectCenter = false; 10855 this.requireInitial = true; // if doesn't start out on a hit, won't emit any events 10856 this.initialHit = null; 10857 this.movingHit = null; 10858 this.finalHit = null; // won't ever be populated if shouldIgnoreMove 10859 this.handlePointerDown = function (ev) { 10860 var dragging = _this.dragging; 10861 _this.initialHit = null; 10862 _this.movingHit = null; 10863 _this.finalHit = null; 10864 _this.prepareHits(); 10865 _this.processFirstCoord(ev); 10866 if (_this.initialHit || !_this.requireInitial) { 10867 dragging.setIgnoreMove(false);
10868 // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :( 10869 _this.emitter.trigger('pointerdown', ev); 10870 } 10871 else { 10872 dragging.setIgnoreMove(true); 10873 } 10874 }; 10875 this.handleDragStart = function (ev) { 10876 _this.emitter.trigger('dragstart', ev); 10877 _this.handleMove(ev, true); // force = fire even if initially null 10878 }; 10879 this.handleDragMove = function (ev) { 10880 _this.emitter.trigger('dragmove', ev); 10881 _this.handleMove(ev); 10882 }; 10883 this.handlePointerUp = function (ev) { 10884 _this.releaseHits(); 10885 _this.emitter.trigger('pointerup', ev); 10886 }; 10887 this.handleDragEnd = function (ev) { 10888 if (_this.movingHit) { 10889 _this.emitter.trigger('hitupdate', null, true, ev); 10890 } 10891 _this.finalHit = _this.movingHit; 10892 _this.movingHit = null; 10893 _this.emitter.trigger('dragend', ev); 10894 }; 10895 this.droppableStore = droppableStore; 10896 dragging.emitter.on('pointerdown', this.handlePointerDown); 10897 dragging.emitter.on('dragstart', this.handleDragStart); 10898 dragging.emitter.on('dragmove', this.handleDragMove); 10899 dragging.emitter.on('pointerup', this.handlePointerUp); 10900 dragging.emitter.on('dragend', this.handleDragEnd); 10901 this.dragging = dragging; 10902 this.emitter = new Emitter(); 10903 } 10904 // sets initialHit 10905 // sets coordAdjust 10906 HitDragging.prototype.processFirstCoord = function (ev) { 10907 var origPoint = { left: ev.pageX, top: ev.pageY }; 10908 var adjustedPoint = origPoint; 10909 var subjectEl = ev.subjectEl; 10910 var subjectRect; 10911 if (subjectEl instanceof HTMLElement) { // i.e. not a Document/ShadowRoot 10912 subjectRect = computeRect(subjectEl); 10913 adjustedPoint = constrainPoint(adjustedPoint, subjectRect); 10914 } 10915 var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top); 10916 if (initialHit) { 10917 if (this.useSubjectCenter && subjectRect) { 10918 var slicedSubjectRect = intersectRects(subjectRect, initialHit.rect); 10919 if (slicedSubjectRect) { 10920 adjustedPoint = getRectCenter(slicedSubjectRect); 10921 } 10922 } 10923 this.coordAdjust = diffPoints(adjustedPoint, origPoint); 10924 } 10925 else { 10926 this.coordAdjust = { left: 0, top: 0 }; 10927 } 10928 }; 10929 HitDragging.prototype.handleMove = function (ev, forceHandle) { 10930 var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top); 10931 if (forceHandle || !isHitsEqual(this.movingHit, hit)) { 10932 this.movingHit = hit; 10933 this.emitter.trigger('hitupdate', hit, false, ev); 10934 } 10935 }; 10936 HitDragging.prototype.prepareHits = function () { 10937 this.offsetTrackers = mapHash(this.droppableStore, function (interactionSettings) { 10938 interactionSettings.component.prepareHits(); 10939 return new OffsetTracker(interactionSettings.el); 10940 }); 10941 }; 10942 HitDragging.prototype.releaseHits = function () { 10943 var offsetTrackers = this.offsetTrackers; 10944 for (var id in offsetTrackers) { 10945 offsetTrackers[id].destroy(); 10946 } 10947 this.offsetTrackers = {}; 10948 }; 10949 HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) { 10950 var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers; 10951 var bestHit = null; 10952 for (var id in droppableStore) { 10953 var component = droppableStore[id].component; 10954 var offsetTracker = offsetTrackers[id]; 10955 if (offsetTracker && // wasn't destroyed mid-drag 10956 offsetTracker.isWithinClipping(offsetLeft, offsetTop)) { 10957 var originLeft = offsetTracker.computeLeft(); 10958 var originTop = offsetTracker.computeTop(); 10959 var positionLeft = offsetLeft - originLeft; 10960 var positionTop = offsetTop - originTop; 10961 var origRect = offsetTracker.origRect; 10962 var width = origRect.right - origRect.left; 10963 var height = origRect.bottom - origRect.top; 10964 if ( 10965 // must be within the element's bounds 10966 positionLeft >= 0 && positionLeft < width && 10967 positionTop >= 0 && positionTop < height) { 10968 var hit = component.queryHit(positionLeft, positionTop, width, height); 10969 if (hit && ( 10970 // make sure the hit is within activeRange, meaning it's not a dead cell 10971 rangeContainsRange(hit.dateProfile.activeRange, hit.dateSpan.range)) && 10972 (!bestHit || hit.layer > bestHit.layer)) { 10973 hit.componentId = id; 10974 hit.context = component.context; 10975 // TODO: better way to re-orient rectangle 10976 hit.rect.left += originLeft; 10977 hit.rect.right += originLeft; 10978 hit.rect.top += originTop; 10979 hit.rect.bottom += originTop; 10980 bestHit = hit; 10981 } 10982 } 10983 } 10984 } 10985 return bestHit; 10986 }; 10987 return HitDragging; 10988 }()); 10989 function isHitsEqual(hit0, hit1) { 10990 if (!hit0 && !hit1) { 10991 return true; 10992 } 10993 if (Boolean(hit0) !== Boolean(hit1)) { 10994 return false; 10995 } 10996 return isDateSpansEqual(hit0.dateSpan, hit1.dateSpan); 10997 } 10998 10999 function buildDatePointApiWithContext(dateSpan, context) { 11000 var props = {}; 11001 for (var _i = 0, _a = context.pluginHooks.datePointTransforms; _i < _a.length; _i++) { 11002 var transform = _a[_i]; 11003 __assign(props, transform(dateSpan, context)); 11004 } 11005 __assign(props, buildDatePointApi(dateSpan, context.dateEnv)); 11006 return props; 11007 } 11008 function buildDatePointApi(span, dateEnv) { 11009 return {
11010 date: dateEnv.toDate(span.range.start), 11011 dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }), 11012 allDay: span.allDay, 11013 }; 11014 } 11015 11016 /* 11017 Monitors when the user clicks on a specific date/time of a component. 11018 A pointerdown+pointerup on the same "hit" constitutes a click. 11019 */ 11020 var DateClicking = /** @class */ (function (_super) { 11021 __extends(DateClicking, _super); 11022 function DateClicking(settings) { 11023 var _this = _super.call(this, settings) || this; 11024 _this.handlePointerDown = function (pev) { 11025 var dragging = _this.dragging; 11026 var downEl = pev.origEvent.target; 11027 // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired 11028 dragging.setIgnoreMove(!_this.component.isValidDateDownEl(downEl)); 11029 }; 11030 // won't even fire if moving was ignored 11031 _this.handleDragEnd = function (ev) { 11032 var component = _this.component; 11033 var pointer = _this.dragging.pointer; 11034 if (!pointer.wasTouchScroll) { 11035 var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit; 11036 if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) { 11037 var context = component.context; 11038 var arg = __assign(__assign({}, buildDatePointApiWithContext(initialHit.dateSpan, context)), { dayEl: initialHit.dayEl, jsEvent: ev.origEvent, view: context.viewApi || context.calendarApi.view }); 11039 context.emitter.trigger('dateClick', arg); 11040 } 11041 } 11042 }; 11043 // we DO want to watch pointer moves because otherwise finalHit won't get populated 11044 _this.dragging = new FeaturefulElementDragging(settings.el); 11045 _this.dragging.autoScroller.isEnabled = false; 11046 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 11047 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11048 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11049 return _this; 11050 } 11051 DateClicking.prototype.destroy = function () { 11052 this.dragging.destroy(); 11053 }; 11054 return DateClicking; 11055 }(Interaction)); 11056 11057 /* 11058 Tracks when the user selects a portion of time of a component, 11059 constituted by a drag over date cells, with a possible delay at the beginning of the drag. 11060 */ 11061 var DateSelecting = /** @class */ (function (_super) { 11062 __extends(DateSelecting, _super); 11063 function DateSelecting(settings) { 11064 var _this = _super.call(this, settings) || this; 11065 _this.dragSelection = null; 11066 _this.handlePointerDown = function (ev) { 11067 var _a = _this, component = _a.component, dragging = _a.dragging; 11068 var options = component.context.options; 11069 var canSelect = options.selectable && 11070 component.isValidDateDownEl(ev.origEvent.target); 11071 // don't bother to watch expensive moves if component won't do selection 11072 dragging.setIgnoreMove(!canSelect); 11073 // if touch, require user to hold down 11074 dragging.delay = ev.isTouch ? getComponentTouchDelay$1(component) : null; 11075 }; 11076 _this.handleDragStart = function (ev) { 11077 _this.component.context.calendarApi.unselect(ev); // unselect previous selections 11078 }; 11079 _this.handleHitUpdate = function (hit, isFinal) { 11080 var context = _this.component.context; 11081 var dragSelection = null; 11082 var isInvalid = false; 11083 if (hit) { 11084 var initialHit = _this.hitDragging.initialHit; 11085 var disallowed = hit.componentId === initialHit.componentId 11086 && _this.isHitComboAllowed 11087 && !_this.isHitComboAllowed(initialHit, hit); 11088 if (!disallowed) { 11089 dragSelection = joinHitsIntoSelection(initialHit, hit, context.pluginHooks.dateSelectionTransformers); 11090 } 11091 if (!dragSelection || !isDateSelectionValid(dragSelection, hit.dateProfile, context)) { 11092 isInvalid = true; 11093 dragSelection = null; 11094 } 11095 } 11096 if (dragSelection) { 11097 context.dispatch({ type: 'SELECT_DATES', selection: dragSelection }); 11098 } 11099 else if (!isFinal) { // only unselect if moved away while dragging 11100 context.dispatch({ type: 'UNSELECT_DATES' }); 11101 } 11102 if (!isInvalid) {
11103 enableCursor(); 11104 } 11105 else { 11106 disableCursor(); 11107 } 11108 if (!isFinal) { 11109 _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging 11110 } 11111 }; 11112 _this.handlePointerUp = function (pev) { 11113 if (_this.dragSelection) { 11114 // selection is already rendered, so just need to report selection 11115 triggerDateSelect(_this.dragSelection, pev, _this.component.context); 11116 _this.dragSelection = null; 11117 } 11118 }; 11119 var component = settings.component; 11120 var options = component.context.options; 11121 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 11122 dragging.touchScrollAllowed = false; 11123 dragging.minDistance = options.selectMinDistance || 0; 11124 dragging.autoScroller.isEnabled = options.dragScroll; 11125 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 11126 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11127 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11128 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11129 hitDragging.emitter.on('pointerup', _this.handlePointerUp); 11130 return _this; 11131 } 11132 DateSelecting.prototype.destroy = function () { 11133 this.dragging.destroy(); 11134 }; 11135 return DateSelecting; 11136 }(Interaction)); 11137 function getComponentTouchDelay$1(component) { 11138 var options = component.context.options; 11139 var delay = options.selectLongPressDelay; 11140 if (delay == null) { 11141 delay = options.longPressDelay; 11142 } 11143 return delay; 11144 } 11145 function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) { 11146 var dateSpan0 = hit0.dateSpan; 11147 var dateSpan1 = hit1.dateSpan; 11148 var ms = [ 11149 dateSpan0.range.start, 11150 dateSpan0.range.end, 11151 dateSpan1.range.start, 11152 dateSpan1.range.end, 11153 ]; 11154 ms.sort(compareNumbers); 11155 var props = {}; 11156 for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) { 11157 var transformer = dateSelectionTransformers_1[_i]; 11158 var res = transformer(hit0, hit1); 11159 if (res === false) { 11160 return null; 11161 } 11162 if (res) { 11163 __assign(props, res); 11164 } 11165 } 11166 props.range = { start: ms[0], end: ms[3] }; 11167 props.allDay = dateSpan0.allDay; 11168 return props; 11169 } 11170 11171 var EventDragging = /** @class */ (function (_super) { 11172 __extends(EventDragging, _super); 11173 function EventDragging(settings) { 11174 var _this = _super.call(this, settings) || this; 11175 // internal state 11176 _this.subjectEl = null; 11177 _this.subjectSeg = null; // the seg being selected/dragged 11178 _this.isDragging = false; 11179 _this.eventRange = null; 11180 _this.relevantEvents = null; // the events being dragged 11181 _this.receivingContext = null; 11182 _this.validMutation = null; 11183 _this.mutatedRelevantEvents = null; 11184 _this.handlePointerDown = function (ev) { 11185 var origTarget = ev.origEvent.target; 11186 var _a = _this, component = _a.component, dragging = _a.dragging; 11187 var mirror = dragging.mirror; 11188 var options = component.context.options; 11189 var initialContext = component.context; 11190 _this.subjectEl = ev.subjectEl; 11191 var subjectSeg = _this.subjectSeg = getElSeg(ev.subjectEl); 11192 var eventRange = _this.eventRange = subjectSeg.eventRange; 11193 var eventInstanceId = eventRange.instance.instanceId; 11194 _this.relevantEvents = getRelevantEvents(initialContext.getCurrentData().eventStore, eventInstanceId); 11195 dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance; 11196 dragging.delay = 11197 // only do a touch delay if touch and this event hasn't been selected yet 11198 (ev.isTouch && eventInstanceId !== component.props.eventSelection) ? 11199 getComponentTouchDelay(component) : 11200 null; 11201 if (options.fixedMirrorParent) { 11202 mirror.parentNode = options.fixedMirrorParent; 11203 } 11204 else { 11205 mirror.parentNode = elementClosest(origTarget, '.fc'); 11206 } 11207 mirror.revertDuration = options.dragRevertDuration; 11208 var isValid = component.isValidSegDownEl(origTarget) && 11209 !elementClosest(origTarget, '.fc-event-resizer'); // NOT on a resizer 11210 dragging.setIgnoreMove(!isValid); 11211 // disable dragging for elements that are resizable (ie, selectable) 11212 // but are not draggable 11213 _this.isDragging = isValid && 11214 ev.subjectEl.classList.contains('fc-event-draggable'); 11215 }; 11216 _this.handleDragStart = function (ev) { 11217 var initialContext = _this.component.context; 11218 var eventRange = _this.eventRange; 11219 var eventInstanceId = eventRange.instance.instanceId; 11220 if (ev.isTouch) { 11221 // need to select a different event? 11222 if (eventInstanceId !== _this.component.props.eventSelection) { 11223 initialContext.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId }); 11224 } 11225 } 11226 else { 11227 // if now using mouse, but was previous touch interaction, clear selected event 11228 initialContext.dispatch({ type: 'UNSELECT_EVENT' }); 11229 } 11230 if (_this.isDragging) { 11231 initialContext.calendarApi.unselect(ev); // unselect *date* selection 11232 initialContext.emitter.trigger('eventDragStart', { 11233 el: _this.subjectEl, 11234 event: new EventApi(initialContext, eventRange.def, eventRange.instance), 11235 jsEvent: ev.origEvent, 11236 view: initialContext.viewApi, 11237 }); 11238 } 11239 }; 11240 _this.handleHitUpdate = function (hit, isFinal) { 11241 if (!_this.isDragging) { 11242 return; 11243 } 11244 var relevantEvents = _this.relevantEvents; 11245 var initialHit = _this.hitDragging.initialHit; 11246 var initialContext = _this.component.context; 11247 // states based on new hit 11248 var receivingContext = null; 11249 var mutation = null; 11250 var mutatedRelevantEvents = null; 11251 var isInvalid = false; 11252 var interaction = { 11253 affectedEvents: relevantEvents, 11254 mutatedEvents: createEmptyEventStore(), 11255 isEvent: true, 11256 }; 11257 if (hit) { 11258 receivingContext = hit.context; 11259 var receivingOptions = receivingContext.options; 11260 if (initialContext === receivingContext || 11261 (receivingOptions.editable && receivingOptions.droppable)) { 11262 mutation = computeEventMutation(initialHit, hit, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers); 11263 if (mutation) { 11264 mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, receivingContext.getCurrentData().eventUiBases, mutation, receivingContext); 11265 interaction.mutatedEvents = mutatedRelevantEvents; 11266 if (!isInteractionValid(interaction, hit.dateProfile, receivingContext)) { 11267 isInvalid = true; 11268 mutation = null; 11269 mutatedRelevantEvents = null; 11270 interaction.mutatedEvents = createEmptyEventStore(); 11271 } 11272 } 11273 } 11274 else { 11275 receivingContext = null; 11276 } 11277 } 11278 _this.displayDrag(receivingContext, interaction); 11279 if (!isInvalid) {
11280 enableCursor(); 11281 } 11282 else { 11283 disableCursor(); 11284 } 11285 if (!isFinal) { 11286 if (initialContext === receivingContext && // TODO: write test for this 11287 isHitsEqual(initialHit, hit)) { 11288 mutation = null; 11289 } 11290 _this.dragging.setMirrorNeedsRevert(!mutation); 11291 // render the mirror if no already-rendered mirror 11292 // TODO: wish we could somehow wait for dispatch to guarantee render 11293 _this.dragging.setMirrorIsVisible(!hit || !getElRoot(_this.subjectEl).querySelector('.fc-event-mirror')); 11294 // assign states based on new hit 11295 _this.receivingContext = receivingContext; 11296 _this.validMutation = mutation; 11297 _this.mutatedRelevantEvents = mutatedRelevantEvents; 11298 } 11299 }; 11300 _this.handlePointerUp = function () { 11301 if (!_this.isDragging) { 11302 _this.cleanup(); // because handleDragEnd won't fire 11303 } 11304 }; 11305 _this.handleDragEnd = function (ev) { 11306 if (_this.isDragging) { 11307 var initialContext_1 = _this.component.context; 11308 var initialView = initialContext_1.viewApi; 11309 var _a = _this, receivingContext_1 = _a.receivingContext, validMutation = _a.validMutation; 11310 var eventDef = _this.eventRange.def; 11311 var eventInstance = _this.eventRange.instance; 11312 var eventApi = new EventApi(initialContext_1, eventDef, eventInstance); 11313 var relevantEvents_1 = _this.relevantEvents; 11314 var mutatedRelevantEvents_1 = _this.mutatedRelevantEvents; 11315 var finalHit = _this.hitDragging.finalHit; 11316 _this.clearDrag(); // must happen after revert animation 11317 initialContext_1.emitter.trigger('eventDragStop', { 11318 el: _this.subjectEl, 11319 event: eventApi, 11320 jsEvent: ev.origEvent, 11321 view: initialView, 11322 }); 11323 if (validMutation) { 11324 // dropped within same calendar 11325 if (receivingContext_1 === initialContext_1) { 11326 var updatedEventApi = new EventApi(initialContext_1, mutatedRelevantEvents_1.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents_1.instances[eventInstance.instanceId] : null); 11327 initialContext_1.dispatch({ 11328 type: 'MERGE_EVENTS', 11329 eventStore: mutatedRelevantEvents_1, 11330 }); 11331 var eventChangeArg = { 11332 oldEvent: eventApi, 11333 event: updatedEventApi, 11334 relatedEvents: buildEventApis(mutatedRelevantEvents_1, initialContext_1, eventInstance), 11335 revert: function () { 11336 initialContext_1.dispatch({ 11337 type: 'MERGE_EVENTS', 11338 eventStore: relevantEvents_1, // the pre-change data 11339 }); 11340 }, 11341 }; 11342 var transformed = {}; 11343 for (var _i = 0, _b = initialContext_1.getCurrentData().pluginHooks.eventDropTransformers; _i < _b.length; _i++) { 11344 var transformer = _b[_i]; 11345 __assign(transformed, transformer(validMutation, initialContext_1)); 11346 } 11347 initialContext_1.emitter.trigger('eventDrop', __assign(__assign(__assign({}, eventChangeArg), transformed), { el: ev.subjectEl, delta: validMutation.datesDelta, jsEvent: ev.origEvent, view: initialView })); 11348 initialContext_1.emitter.trigger('eventChange', eventChangeArg); 11349 // dropped in different calendar 11350 } 11351 else if (receivingContext_1) { 11352 var eventRemoveArg = { 11353 event: eventApi, 11354 relatedEvents: buildEventApis(relevantEvents_1, initialContext_1, eventInstance), 11355 revert: function () { 11356 initialContext_1.dispatch({ 11357 type: 'MERGE_EVENTS', 11358 eventStore: relevantEvents_1, 11359 }); 11360 }, 11361 }; 11362 initialContext_1.emitter.trigger('eventLeave', __assign(__assign({}, eventRemoveArg), { draggedEl: ev.subjectEl, view: initialView })); 11363 initialContext_1.dispatch({
11364 type: 'REMOVE_EVENTS', 11365 eventStore: relevantEvents_1, 11366 }); 11367 initialContext_1.emitter.trigger('eventRemove', eventRemoveArg); 11368 var addedEventDef = mutatedRelevantEvents_1.defs[eventDef.defId]; 11369 var addedEventInstance = mutatedRelevantEvents_1.instances[eventInstance.instanceId]; 11370 var addedEventApi = new EventApi(receivingContext_1, addedEventDef, addedEventInstance); 11371 receivingContext_1.dispatch({ 11372 type: 'MERGE_EVENTS', 11373 eventStore: mutatedRelevantEvents_1, 11374 }); 11375 var eventAddArg = { 11376 event: addedEventApi, 11377 relatedEvents: buildEventApis(mutatedRelevantEvents_1, receivingContext_1, addedEventInstance), 11378 revert: function () { 11379 receivingContext_1.dispatch({ 11380 type: 'REMOVE_EVENTS', 11381 eventStore: mutatedRelevantEvents_1, 11382 }); 11383 }, 11384 }; 11385 receivingContext_1.emitter.trigger('eventAdd', eventAddArg); 11386 if (ev.isTouch) { 11387 receivingContext_1.dispatch({ 11388 type: 'SELECT_EVENT', 11389 eventInstanceId: eventInstance.instanceId, 11390 }); 11391 } 11392 receivingContext_1.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext_1)), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.context.viewApi })); 11393 receivingContext_1.emitter.trigger('eventReceive', __assign(__assign({}, eventAddArg), { draggedEl: ev.subjectEl, view: finalHit.context.viewApi })); 11394 } 11395 } 11396 else { 11397 initialContext_1.emitter.trigger('_noEventDrop'); 11398 } 11399 } 11400 _this.cleanup(); 11401 }; 11402 var component = _this.component; 11403 var options = component.context.options; 11404 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 11405 dragging.pointer.selector = EventDragging.SELECTOR; 11406 dragging.touchScrollAllowed = false; 11407 dragging.autoScroller.isEnabled = options.dragScroll; 11408 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsStore); 11409 hitDragging.useSubjectCenter = settings.useEventCenter; 11410 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11411 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11412 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11413 hitDragging.emitter.on('pointerup', _this.handlePointerUp); 11414 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11415 return _this; 11416 } 11417 EventDragging.prototype.destroy = function () { 11418 this.dragging.destroy(); 11419 }; 11420 // render a drag state on the next receivingCalendar 11421 EventDragging.prototype.displayDrag = function (nextContext, state) { 11422 var initialContext = this.component.context; 11423 var prevContext = this.receivingContext; 11424 // does the previous calendar need to be cleared? 11425 if (prevContext && prevContext !== nextContext) { 11426 // does the initial calendar need to be cleared? 11427 // if so, don't clear all the way. we still need to to hide the affectedEvents 11428 if (prevContext === initialContext) { 11429 prevContext.dispatch({ 11430 type: 'SET_EVENT_DRAG', 11431 state: { 11432 affectedEvents: state.affectedEvents, 11433 mutatedEvents: createEmptyEventStore(), 11434 isEvent: true, 11435 }, 11436 }); 11437 // completely clear the old calendar if it wasn't the initial 11438 } 11439 else { 11440 prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11441 } 11442 } 11443 if (nextContext) { 11444 nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state }); 11445 } 11446 }; 11447 EventDragging.prototype.clearDrag = function () { 11448 var initialCalendar = this.component.context; 11449 var receivingContext = this.receivingContext; 11450 if (receivingContext) { 11451 receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11452 } 11453 // the initial calendar might have an dummy drag state from displayDrag 11454 if (initialCalendar !== receivingContext) { 11455 initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11456 } 11457 }; 11458 EventDragging.prototype.cleanup = function () { 11459 this.subjectSeg = null; 11460 this.isDragging = false; 11461 this.eventRange = null; 11462 this.relevantEvents = null; 11463 this.receivingContext = null; 11464 this.validMutation = null; 11465 this.mutatedRelevantEvents = null; 11466 }; 11467 // TODO: test this in IE11 11468 // QUESTION: why do we need it on the resizable??? 11469 EventDragging.SELECTOR = '.fc-event-draggable, .fc-event-resizable'; 11470 return EventDragging; 11471 }(Interaction)); 11472 function computeEventMutation(hit0, hit1, massagers) { 11473 var dateSpan0 = hit0.dateSpan; 11474 var dateSpan1 = hit1.dateSpan; 11475 var date0 = dateSpan0.range.start; 11476 var date1 = dateSpan1.range.start; 11477 var standardProps = {}; 11478 if (dateSpan0.allDay !== dateSpan1.allDay) { 11479 standardProps.allDay = dateSpan1.allDay; 11480 standardProps.hasEnd = hit1.context.options.allDayMaintainDuration; 11481 if (dateSpan1.allDay) { 11482 // means date1 is already start-of-day, 11483 // but date0 needs to be converted 11484 date0 = startOfDay(date0); 11485 } 11486 } 11487 var delta = diffDates(date0, date1, hit0.context.dateEnv, hit0.componentId === hit1.componentId ? 11488 hit0.largeUnit : 11489 null); 11490 if (delta.milliseconds) { // has hours/minutes/seconds 11491 standardProps.allDay = false; 11492 } 11493 var mutation = { 11494 datesDelta: delta, 11495 standardProps: standardProps, 11496 }; 11497 for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) { 11498 var massager = massagers_1[_i]; 11499 massager(mutation, hit0, hit1); 11500 } 11501 return mutation; 11502 } 11503 function getComponentTouchDelay(component) { 11504 var options = component.context.options;
11505 var delay = options.eventLongPressDelay; 11506 if (delay == null) { 11507 delay = options.longPressDelay; 11508 } 11509 return delay; 11510 } 11511 11512 var EventResizing = /** @class */ (function (_super) { 11513 __extends(EventResizing, _super); 11514 function EventResizing(settings) { 11515 var _this = _super.call(this, settings) || this; 11516 // internal state 11517 _this.draggingSegEl = null; 11518 _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg? 11519 _this.eventRange = null; 11520 _this.relevantEvents = null; 11521 _this.validMutation = null; 11522 _this.mutatedRelevantEvents = null; 11523 _this.handlePointerDown = function (ev) { 11524 var component = _this.component; 11525 var segEl = _this.querySegEl(ev); 11526 var seg = getElSeg(segEl); 11527 var eventRange = _this.eventRange = seg.eventRange; 11528 _this.dragging.minDistance = component.context.options.eventDragMinDistance; 11529 // if touch, need to be working with a selected event 11530 _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) || 11531 (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId)); 11532 }; 11533 _this.handleDragStart = function (ev) { 11534 var context = _this.component.context; 11535 var eventRange = _this.eventRange; 11536 _this.relevantEvents = getRelevantEvents(context.getCurrentData().eventStore, _this.eventRange.instance.instanceId); 11537 var segEl = _this.querySegEl(ev); 11538 _this.draggingSegEl = segEl; 11539 _this.draggingSeg = getElSeg(segEl); 11540 context.calendarApi.unselect(); 11541 context.emitter.trigger('eventResizeStart', { 11542 el: segEl, 11543 event: new EventApi(context, eventRange.def, eventRange.instance), 11544 jsEvent: ev.origEvent, 11545 view: context.viewApi, 11546 }); 11547 }; 11548 _this.handleHitUpdate = function (hit, isFinal, ev) { 11549 var context = _this.component.context; 11550 var relevantEvents = _this.relevantEvents; 11551 var initialHit = _this.hitDragging.initialHit; 11552 var eventInstance = _this.eventRange.instance; 11553 var mutation = null; 11554 var mutatedRelevantEvents = null; 11555 var isInvalid = false; 11556 var interaction = { 11557 affectedEvents: relevantEvents, 11558 mutatedEvents: createEmptyEventStore(), 11559 isEvent: true, 11560 }; 11561 if (hit) { 11562 var disallowed = hit.componentId === initialHit.componentId 11563 && _this.isHitComboAllowed 11564 && !_this.isHitComboAllowed(initialHit, hit); 11565 if (!disallowed) { 11566 mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-event-resizer-start'), eventInstance.range); 11567 } 11568 } 11569 if (mutation) { 11570 mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, context.getCurrentData().eventUiBases, mutation, context); 11571 interaction.mutatedEvents = mutatedRelevantEvents; 11572 if (!isInteractionValid(interaction, hit.dateProfile, context)) { 11573 isInvalid = true; 11574 mutation = null; 11575 mutatedRelevantEvents = null; 11576 interaction.mutatedEvents = null; 11577 } 11578 } 11579 if (mutatedRelevantEvents) { 11580 context.dispatch({ 11581 type: 'SET_EVENT_RESIZE', 11582 state: interaction, 11583 }); 11584 } 11585 else { 11586 context.dispatch({ type: 'UNSET_EVENT_RESIZE' }); 11587 } 11588 if (!isInvalid) {
11589 enableCursor(); 11590 } 11591 else { 11592 disableCursor(); 11593 } 11594 if (!isFinal) { 11595 if (mutation && isHitsEqual(initialHit, hit)) { 11596 mutation = null; 11597 } 11598 _this.validMutation = mutation; 11599 _this.mutatedRelevantEvents = mutatedRelevantEvents; 11600 } 11601 }; 11602 _this.handleDragEnd = function (ev) { 11603 var context = _this.component.context; 11604 var eventDef = _this.eventRange.def; 11605 var eventInstance = _this.eventRange.instance; 11606 var eventApi = new EventApi(context, eventDef, eventInstance); 11607 var relevantEvents = _this.relevantEvents; 11608 var mutatedRelevantEvents = _this.mutatedRelevantEvents; 11609 context.emitter.trigger('eventResizeStop', { 11610 el: _this.draggingSegEl, 11611 event: eventApi, 11612 jsEvent: ev.origEvent, 11613 view: context.viewApi, 11614 }); 11615 if (_this.validMutation) { 11616 var updatedEventApi = new EventApi(context, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null); 11617 context.dispatch({ 11618 type: 'MERGE_EVENTS', 11619 eventStore: mutatedRelevantEvents, 11620 }); 11621 var eventChangeArg = { 11622 oldEvent: eventApi, 11623 event: updatedEventApi, 11624 relatedEvents: buildEventApis(mutatedRelevantEvents, context, eventInstance), 11625 revert: function () { 11626 context.dispatch({ 11627 type: 'MERGE_EVENTS', 11628 eventStore: relevantEvents, // the pre-change events 11629 }); 11630 }, 11631 }; 11632 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 })); 11633 context.emitter.trigger('eventChange', eventChangeArg); 11634 } 11635 else { 11636 context.emitter.trigger('_noEventResize'); 11637 } 11638 // reset all internal state 11639 _this.draggingSeg = null; 11640 _this.relevantEvents = null; 11641 _this.validMutation = null; 11642 // okay to keep eventInstance around. useful to set it in handlePointerDown 11643 }; 11644 var component = settings.component; 11645 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 11646 dragging.pointer.selector = '.fc-event-resizer'; 11647 dragging.touchScrollAllowed = false; 11648 dragging.autoScroller.isEnabled = component.context.options.dragScroll; 11649 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 11650 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11651 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11652 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11653 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11654 return _this; 11655 } 11656 EventResizing.prototype.destroy = function () { 11657 this.dragging.destroy(); 11658 }; 11659 EventResizing.prototype.querySegEl = function (ev) { 11660 return elementClosest(ev.subjectEl, '.fc-event'); 11661 }; 11662 return EventResizing; 11663 }(Interaction)); 11664 function computeMutation(hit0, hit1, isFromStart, instanceRange) { 11665 var dateEnv = hit0.context.dateEnv; 11666 var date0 = hit0.dateSpan.range.start; 11667 var date1 = hit1.dateSpan.range.start; 11668 var delta = diffDates(date0, date1, dateEnv, hit0.largeUnit); 11669 if (isFromStart) { 11670 if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) { 11671 return { startDelta: delta }; 11672 } 11673 } 11674 else if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) { 11675 return { endDelta: delta }; 11676 } 11677 return null; 11678 } 11679 11680 var UnselectAuto = /** @class */ (function () { 11681 function UnselectAuto(context) { 11682 var _this = this; 11683 this.context = context; 11684 this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system 11685 this.matchesCancel = false; 11686 this.matchesEvent = false; 11687 this.onSelect = function (selectInfo) { 11688 if (selectInfo.jsEvent) { 11689 _this.isRecentPointerDateSelect = true; 11690 } 11691 }; 11692 this.onDocumentPointerDown = function (pev) { 11693 var unselectCancel = _this.context.options.unselectCancel; 11694 var downEl = getEventTargetViaRoot(pev.origEvent); 11695 _this.matchesCancel = !!elementClosest(downEl, unselectCancel); 11696 _this.matchesEvent = !!elementClosest(downEl, EventDragging.SELECTOR); // interaction started on an event? 11697 }; 11698 this.onDocumentPointerUp = function (pev) { 11699 var context = _this.context; 11700 var documentPointer = _this.documentPointer; 11701 var calendarState = context.getCurrentData(); 11702 // touch-scrolling should never unfocus any type of selection 11703 if (!documentPointer.wasTouchScroll) { 11704 if (calendarState.dateSelection && // an existing date selection? 11705 !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp? 11706 ) { 11707 var unselectAuto = context.options.unselectAuto; 11708 if (unselectAuto && (!unselectAuto || !_this.matchesCancel)) { 11709 context.calendarApi.unselect(pev); 11710 } 11711 } 11712 if (calendarState.eventSelection && // an existing event selected? 11713 !_this.matchesEvent // interaction DIDN'T start on an event 11714 ) { 11715 context.dispatch({ type: 'UNSELECT_EVENT' }); 11716 } 11717 } 11718 _this.isRecentPointerDateSelect = false; 11719 }; 11720 var documentPointer = this.documentPointer = new PointerDragging(document); 11721 documentPointer.shouldIgnoreMove = true; 11722 documentPointer.shouldWatchScroll = false; 11723 documentPointer.emitter.on('pointerdown', this.onDocumentPointerDown);
11724 documentPointer.emitter.on('pointerup', this.onDocumentPointerUp); 11725 /* 11726 TODO: better way to know about whether there was a selection with the pointer 11727 */ 11728 context.emitter.on('select', this.onSelect); 11729 } 11730 UnselectAuto.prototype.destroy = function () { 11731 this.context.emitter.off('select', this.onSelect); 11732 this.documentPointer.destroy(); 11733 }; 11734 return UnselectAuto; 11735 }()); 11736 11737 var OPTION_REFINERS$3 = { 11738 fixedMirrorParent: identity, 11739 }; 11740 var LISTENER_REFINERS = { 11741 dateClick: identity, 11742 eventDragStart: identity, 11743 eventDragStop: identity, 11744 eventDrop: identity, 11745 eventResizeStart: identity, 11746 eventResizeStop: identity, 11747 eventResize: identity, 11748 drop: identity, 11749 eventReceive: identity, 11750 eventLeave: identity, 11751 }; 11752 11753 /* 11754 Given an already instantiated draggable object for one-or-more elements, 11755 Interprets any dragging as an attempt to drag an events that lives outside 11756 of a calendar onto a calendar. 11757 */ 11758 var ExternalElementDragging = /** @class */ (function () { 11759 function ExternalElementDragging(dragging, suppliedDragMeta) { 11760 var _this = this; 11761 this.receivingContext = null; 11762 this.droppableEvent = null; // will exist for all drags, even if create:false 11763 this.suppliedDragMeta = null; 11764 this.dragMeta = null; 11765 this.handleDragStart = function (ev) { 11766 _this.dragMeta = _this.buildDragMeta(ev.subjectEl); 11767 }; 11768 this.handleHitUpdate = function (hit, isFinal, ev) { 11769 var dragging = _this.hitDragging.dragging; 11770 var receivingContext = null; 11771 var droppableEvent = null; 11772 var isInvalid = false; 11773 var interaction = { 11774 affectedEvents: createEmptyEventStore(), 11775 mutatedEvents: createEmptyEventStore(), 11776 isEvent: _this.dragMeta.create, 11777 }; 11778 if (hit) { 11779 receivingContext = hit.context; 11780 if (_this.canDropElOnCalendar(ev.subjectEl, receivingContext)) { 11781 droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingContext); 11782 interaction.mutatedEvents = eventTupleToStore(droppableEvent); 11783 isInvalid = !isInteractionValid(interaction, hit.dateProfile, receivingContext); 11784 if (isInvalid) { 11785 interaction.mutatedEvents = createEmptyEventStore(); 11786 droppableEvent = null; 11787 } 11788 } 11789 } 11790 _this.displayDrag(receivingContext, interaction); 11791 // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?) 11792 // TODO: wish we could somehow wait for dispatch to guarantee render 11793 dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-event-mirror')); 11794 if (!isInvalid) { 11795 enableCursor(); 11796 } 11797 else { 11798 disableCursor(); 11799 } 11800 if (!isFinal) { 11801 dragging.setMirrorNeedsRevert(!droppableEvent); 11802 _this.receivingContext = receivingContext; 11803 _this.droppableEvent = droppableEvent; 11804 } 11805 }; 11806 this.handleDragEnd = function (pev) { 11807 var _a = _this, receivingContext = _a.receivingContext, droppableEvent = _a.droppableEvent; 11808 _this.clearDrag(); 11809 if (receivingContext && droppableEvent) { 11810 var finalHit = _this.hitDragging.finalHit; 11811 var finalView = finalHit.context.viewApi; 11812 var dragMeta = _this.dragMeta; 11813 receivingContext.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView })); 11814 if (dragMeta.create) { 11815 var addingEvents_1 = eventTupleToStore(droppableEvent); 11816 receivingContext.dispatch({ 11817 type: 'MERGE_EVENTS', 11818 eventStore: addingEvents_1, 11819 }); 11820 if (pev.isTouch) { 11821 receivingContext.dispatch({ 11822 type: 'SELECT_EVENT', 11823 eventInstanceId: droppableEvent.instance.instanceId, 11824 }); 11825 } 11826 // signal that an external event landed 11827 receivingContext.emitter.trigger('eventReceive', { 11828 event: new EventApi(receivingContext, droppableEvent.def, droppableEvent.instance), 11829 relatedEvents: [], 11830 revert: function () { 11831 receivingContext.dispatch({
11832 type: 'REMOVE_EVENTS', 11833 eventStore: addingEvents_1, 11834 }); 11835 }, 11836 draggedEl: pev.subjectEl, 11837 view: finalView, 11838 }); 11839 } 11840 } 11841 _this.receivingContext = null; 11842 _this.droppableEvent = null; 11843 }; 11844 var hitDragging = this.hitDragging = new HitDragging(dragging, interactionSettingsStore); 11845 hitDragging.requireInitial = false; // will start outside of a component 11846 hitDragging.emitter.on('dragstart', this.handleDragStart); 11847 hitDragging.emitter.on('hitupdate', this.handleHitUpdate); 11848 hitDragging.emitter.on('dragend', this.handleDragEnd); 11849 this.suppliedDragMeta = suppliedDragMeta; 11850 } 11851 ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) { 11852 if (typeof this.suppliedDragMeta === 'object') { 11853 return parseDragMeta(this.suppliedDragMeta); 11854 } 11855 if (typeof this.suppliedDragMeta === 'function') { 11856 return parseDragMeta(this.suppliedDragMeta(subjectEl)); 11857 } 11858 return getDragMetaFromEl(subjectEl); 11859 }; 11860 ExternalElementDragging.prototype.displayDrag = function (nextContext, state) { 11861 var prevContext = this.receivingContext; 11862 if (prevContext && prevContext !== nextContext) { 11863 prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11864 } 11865 if (nextContext) { 11866 nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state }); 11867 } 11868 }; 11869 ExternalElementDragging.prototype.clearDrag = function () { 11870 if (this.receivingContext) { 11871 this.receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11872 } 11873 }; 11874 ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingContext) { 11875 var dropAccept = receivingContext.options.dropAccept; 11876 if (typeof dropAccept === 'function') { 11877 return dropAccept.call(receivingContext.calendarApi, el); 11878 } 11879 if (typeof dropAccept === 'string' && dropAccept) { 11880 return Boolean(elementMatches(el, dropAccept)); 11881 } 11882 return true; 11883 }; 11884 return ExternalElementDragging; 11885 }()); 11886 // Utils for computing event store from the DragMeta 11887 // ---------------------------------------------------------------------------------------------------- 11888 function computeEventForDateSpan(dateSpan, dragMeta, context) { 11889 var defProps = __assign({}, dragMeta.leftoverProps); 11890 for (var _i = 0, _a = context.pluginHooks.externalDefTransforms; _i < _a.length; _i++) { 11891 var transform = _a[_i]; 11892 __assign(defProps, transform(dateSpan, dragMeta)); 11893 } 11894 var _b = refineEventDef(defProps, context), refined = _b.refined, extra = _b.extra; 11895 var def = parseEventDef(refined, extra, dragMeta.sourceId, dateSpan.allDay, context.options.forceEventDuration || Boolean(dragMeta.duration), // hasEnd 11896 context); 11897 var start = dateSpan.range.start; 11898 // only rely on time info if drop zone is all-day, 11899 // otherwise, we already know the time 11900 if (dateSpan.allDay && dragMeta.startTime) { 11901 start = context.dateEnv.add(start, dragMeta.startTime); 11902 } 11903 var end = dragMeta.duration ? 11904 context.dateEnv.add(start, dragMeta.duration) : 11905 getDefaultEventEnd(dateSpan.allDay, start, context); 11906 var instance = createEventInstance(def.defId, { start: start, end: end }); 11907 return { def: def, instance: instance }; 11908 } 11909 // Utils for extracting data from element 11910 // ---------------------------------------------------------------------------------------------------- 11911 function getDragMetaFromEl(el) { 11912 var str = getEmbeddedElData(el, 'event'); 11913 var obj = str ? 11914 JSON.parse(str) : 11915 { create: false }; // if no embedded data, assume no event creation 11916 return parseDragMeta(obj); 11917 } 11918 config.dataAttrPrefix = ''; 11919 function getEmbeddedElData(el, name) { 11920 var prefix = config.dataAttrPrefix; 11921 var prefixedName = (prefix ? prefix + '-' : '') + name; 11922 return el.getAttribute('data-' + prefixedName) || ''; 11923 } 11924 11925 /* 11926 Makes an element (that is *external* to any calendar) draggable. 11927 Can pass in data that determines how an event will be created when dropped onto a calendar. 11928 Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system. 11929 */
11930 var ExternalDraggable = /** @class */ (function () { 11931 function ExternalDraggable(el, settings) { 11932 var _this = this; 11933 if (settings === void 0) { settings = {}; } 11934 this.handlePointerDown = function (ev) { 11935 var dragging = _this.dragging; 11936 var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay; 11937 dragging.minDistance = 11938 minDistance != null ? 11939 minDistance : 11940 (ev.isTouch ? 0 : BASE_OPTION_DEFAULTS.eventDragMinDistance); 11941 dragging.delay = 11942 ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv 11943 (longPressDelay != null ? longPressDelay : BASE_OPTION_DEFAULTS.longPressDelay) : 11944 0; 11945 }; 11946 this.handleDragStart = function (ev) { 11947 if (ev.isTouch && 11948 _this.dragging.delay && 11949 ev.subjectEl.classList.contains('fc-event')) { 11950 _this.dragging.mirror.getMirrorEl().classList.add('fc-event-selected'); 11951 } 11952 }; 11953 this.settings = settings; 11954 var dragging = this.dragging = new FeaturefulElementDragging(el); 11955 dragging.touchScrollAllowed = false; 11956 if (settings.itemSelector != null) { 11957 dragging.pointer.selector = settings.itemSelector; 11958 } 11959 if (settings.appendTo != null) { 11960 dragging.mirror.parentNode = settings.appendTo; // TODO: write tests 11961 } 11962 dragging.emitter.on('pointerdown', this.handlePointerDown); 11963 dragging.emitter.on('dragstart', this.handleDragStart); 11964 new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new 11965 } 11966 ExternalDraggable.prototype.destroy = function () { 11967 this.dragging.destroy(); 11968 }; 11969 return ExternalDraggable; 11970 }()); 11971 11972 /* 11973 Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements. 11974 The third-party system is responsible for drawing the visuals effects of the drag. 11975 This class simply monitors for pointer movements and fires events. 11976 It also has the ability to hide the moving element (the "mirror") during the drag. 11977 */ 11978 var InferredElementDragging = /** @class */ (function (_super) { 11979 __extends(InferredElementDragging, _super); 11980 function InferredElementDragging(containerEl) { 11981 var _this = _super.call(this, containerEl) || this; 11982 _this.shouldIgnoreMove = false; 11983 _this.mirrorSelector = ''; 11984 _this.currentMirrorEl = null; 11985 _this.handlePointerDown = function (ev) { 11986 _this.emitter.trigger('pointerdown', ev); 11987 if (!_this.shouldIgnoreMove) { 11988 // fire dragstart right away. does not support delay or min-distance 11989 _this.emitter.trigger('dragstart', ev); 11990 } 11991 }; 11992 _this.handlePointerMove = function (ev) { 11993 if (!_this.shouldIgnoreMove) { 11994 _this.emitter.trigger('dragmove', ev); 11995 } 11996 }; 11997 _this.handlePointerUp = function (ev) { 11998 _this.emitter.trigger('pointerup', ev); 11999 if (!_this.shouldIgnoreMove) { 12000 // fire dragend right away. does not support a revert animation 12001 _this.emitter.trigger('dragend', ev); 12002 } 12003 }; 12004 var pointer = _this.pointer = new PointerDragging(containerEl); 12005 pointer.emitter.on('pointerdown', _this.handlePointerDown); 12006 pointer.emitter.on('pointermove', _this.handlePointerMove); 12007 pointer.emitter.on('pointerup', _this.handlePointerUp); 12008 return _this; 12009 } 12010 InferredElementDragging.prototype.destroy = function () { 12011 this.pointer.destroy(); 12012 }; 12013 InferredElementDragging.prototype.setIgnoreMove = function (bool) { 12014 this.shouldIgnoreMove = bool; 12015 }; 12016 InferredElementDragging.prototype.setMirrorIsVisible = function (bool) { 12017 if (bool) { 12018 // restore a previously hidden element. 12019 // use the reference in case the selector class has already been removed. 12020 if (this.currentMirrorEl) { 12021 this.currentMirrorEl.style.visibility = ''; 12022 this.currentMirrorEl = null; 12023 } 12024 } 12025 else { 12026 var mirrorEl = this.mirrorSelector 12027 // TODO: somehow query FullCalendars WITHIN shadow-roots 12028 ? document.querySelector(this.mirrorSelector) 12029 : null; 12030 if (mirrorEl) { 12031 this.currentMirrorEl = mirrorEl; 12032 mirrorEl.style.visibility = 'hidden'; 12033 } 12034 } 12035 }; 12036 return InferredElementDragging; 12037 }(ElementDragging)); 12038 12039 /* 12040 Bridges third-party drag-n-drop systems with FullCalendar. 12041 Must be instantiated and destroyed by caller. 12042 */ 12043 var ThirdPartyDraggable = /** @class */ (function () { 12044 function ThirdPartyDraggable(containerOrSettings, settings) { 12045 var containerEl = document; 12046 if ( 12047 // wish we could just test instanceof EventTarget, but doesn't work in IE11 12048 containerOrSettings === document || 12049 containerOrSettings instanceof Element) { 12050 containerEl = containerOrSettings; 12051 settings = settings || {}; 12052 } 12053 else { 12054 settings = (containerOrSettings || {}); 12055 } 12056 var dragging = this.dragging = new InferredElementDragging(containerEl); 12057 if (typeof settings.itemSelector === 'string') { 12058 dragging.pointer.selector = settings.itemSelector; 12059 } 12060 else if (containerEl === document) { 12061 dragging.pointer.selector = '[data-event]'; 12062 } 12063 if (typeof settings.mirrorSelector === 'string') { 12064 dragging.mirrorSelector = settings.mirrorSelector; 12065 } 12066 new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new 12067 } 12068 ThirdPartyDraggable.prototype.destroy = function () { 12069 this.dragging.destroy(); 12070 }; 12071 return ThirdPartyDraggable; 12072 }()); 12073 12074 var interactionPlugin = createPlugin({ 12075 componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing], 12076 calendarInteractions: [UnselectAuto], 12077 elementDraggingImpl: FeaturefulElementDragging, 12078 optionRefiners: OPTION_REFINERS$3, 12079 listenerRefiners: LISTENER_REFINERS, 12080 });
12081 12082 /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells. 12083 ----------------------------------------------------------------------------------------------------------------------*/ 12084 // It is a manager for a Table subcomponent, which does most of the heavy lifting. 12085 // It is responsible for managing width/height. 12086 var TableView = /** @class */ (function (_super) { 12087 __extends(TableView, _super); 12088 function TableView() { 12089 var _this = _super !== null && _super.apply(this, arguments) || this; 12090 _this.headerElRef = createRef(); 12091 return _this; 12092 } 12093 TableView.prototype.renderSimpleLayout = function (headerRowContent, bodyContent) { 12094 var _a = this, props = _a.props, context = _a.context; 12095 var sections = []; 12096 var stickyHeaderDates = getStickyHeaderDates(context.options); 12097 if (headerRowContent) { 12098 sections.push({ 12099 type: 'header', 12100 key: 'header', 12101 isSticky: stickyHeaderDates, 12102 chunk: { 12103 elRef: this.headerElRef, 12104 tableClassName: 'fc-col-header', 12105 rowContent: headerRowContent, 12106 }, 12107 }); 12108 } 12109 sections.push({ 12110 type: 'body', 12111 key: 'body', 12112 liquid: true, 12113 chunk: { content: bodyContent }, 12114 }); 12115 return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygrid'].concat(classNames).join(' ') }, 12116 createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [] /* TODO: make optional? */, sections: sections }))); })); 12117 }; 12118 TableView.prototype.renderHScrollLayout = function (headerRowContent, bodyContent, colCnt, dayMinWidth) { 12119 var ScrollGrid = this.context.pluginHooks.scrollGridImpl; 12120 if (!ScrollGrid) { 12121 throw new Error('No ScrollGrid implementation'); 12122 } 12123 var _a = this, props = _a.props, context = _a.context; 12124 var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options); 12125 var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options); 12126 var sections = []; 12127 if (headerRowContent) { 12128 sections.push({ 12129 type: 'header', 12130 key: 'header', 12131 isSticky: stickyHeaderDates, 12132 chunks: [{ 12133 key: 'main', 12134 elRef: this.headerElRef, 12135 tableClassName: 'fc-col-header', 12136 rowContent: headerRowContent, 12137 }], 12138 }); 12139 } 12140 sections.push({ 12141 type: 'body', 12142 key: 'body', 12143 liquid: true, 12144 chunks: [{ 12145 key: 'main', 12146 content: bodyContent, 12147 }], 12148 }); 12149 if (stickyFooterScrollbar) { 12150 sections.push({ 12151 type: 'footer', 12152 key: 'footer', 12153 isSticky: true, 12154 chunks: [{ 12155 key: 'main', 12156 content: renderScrollShim, 12157 }], 12158 }); 12159 } 12160 return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygrid'].concat(classNames).join(' ') }, 12161 createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], sections: sections }))); })); 12162 }; 12163 return TableView; 12164 }(DateComponent)); 12165 12166 function splitSegsByRow(segs, rowCnt) { 12167 var byRow = []; 12168 for (var i = 0; i < rowCnt; i += 1) { 12169 byRow[i] = []; 12170 } 12171 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 12172 var seg = segs_1[_i]; 12173 byRow[seg.row].push(seg); 12174 } 12175 return byRow; 12176 } 12177 function splitSegsByFirstCol(segs, colCnt) { 12178 var byCol = []; 12179 for (var i = 0; i < colCnt; i += 1) { 12180 byCol[i] = []; 12181 } 12182 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 12183 var seg = segs_2[_i]; 12184 byCol[seg.firstCol].push(seg); 12185 } 12186 return byCol; 12187 } 12188 function splitInteractionByRow(ui, rowCnt) { 12189 var byRow = []; 12190 if (!ui) { 12191 for (var i = 0; i < rowCnt; i += 1) { 12192 byRow[i] = null; 12193 } 12194 } 12195 else { 12196 for (var i = 0; i < rowCnt; i += 1) { 12197 byRow[i] = { 12198 affectedInstances: ui.affectedInstances, 12199 isEvent: ui.isEvent, 12200 segs: [], 12201 }; 12202 } 12203 for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) { 12204 var seg = _a[_i]; 12205 byRow[seg.row].segs.push(seg); 12206 } 12207 } 12208 return byRow; 12209 } 12210 12211 var TableCellTop = /** @class */ (function (_super) { 12212 __extends(TableCellTop, _super); 12213 function TableCellTop() { 12214 return _super !== null && _super.apply(this, arguments) || this; 12215 } 12216 TableCellTop.prototype.render = function () { 12217 var props = this.props; 12218 var navLinkAttrs = buildNavLinkAttrs(this.context, props.date); 12219 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
12219d-day-top", ref: innerElRef }, 12220 createElement("a", __assign({ id: props.dayNumberId, className: "fc-daygrid-day-number" }, navLinkAttrs), innerContent || createElement(Fragment, null, "\u00A0"))))); })); 12221 }; 12222 return TableCellTop; 12223 }(BaseComponent)); 12224 function renderTopInner(props) { 12225 return props.dayNumberText; 12226 } 12227 12228 var DEFAULT_TABLE_EVENT_TIME_FORMAT = createFormatter({ 12229 hour: 'numeric', 12230 minute: '2-digit', 12231 omitZeroMinute: true, 12232 meridiem: 'narrow', 12233 }); 12234 function hasListItemDisplay(seg) { 12235 var display = seg.eventRange.ui.display; 12236 return display === 'list-item' || (display === 'auto' && 12237 !seg.eventRange.def.allDay && 12238 seg.firstCol === seg.lastCol && // can't be multi-day 12239 seg.isStart && // " 12240 seg.isEnd // " 12241 ); 12242 } 12243 12244 var TableBlockEvent = /** @class */ (function (_super) { 12245 __extends(TableBlockEvent, _super); 12246 function TableBlockEvent() { 12247 return _super !== null && _super.apply(this, arguments) || this; 12248 } 12249 TableBlockEvent.prototype.render = function () { 12250 var props = this.props; 12251 return (createElement(StandardEvent, __assign({}
12251, 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 }))); 12252 }; 12253 return TableBlockEvent; 12254 }(BaseComponent)); 12255 12256 var TableListItemEvent = /** @class */ (function (_super) { 12257 __extends(TableListItemEvent, _super); 12258 function TableListItemEvent() { 12259 return _super !== null && _super.apply(this, arguments) || this; 12260 } 12261 TableListItemEvent.prototype.render = function () { 12262 var _a = this, props = _a.props, context = _a.context; 12263 var timeFormat = context.options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT; 12264 var timeText = buildSegTimeText(props.seg, timeFormat, context, true, props.defaultDisplayEventEnd); 12265 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! 12266 createElement("a", __assign({ className: ['fc-daygrid-event', 'fc-daygri
12266d-dot-event'].concat(classNames).join(' '), ref: rootElRef }, getSegAnchorAttrs(props.seg, context)), innerContent)); })); 12267 }; 12268 return TableListItemEvent; 12269 }(BaseComponent)); 12270 function renderInnerContent$2(innerProps) { 12271 return (createElement(Fragment, null, 12272 createElement("div", { className: "fc-daygrid-event-dot", style: { borderColor: innerProps.borderColor || innerProps.backgroundColor } }), 12273 innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)), 12274 createElement("div", { className: "fc-event-title" }, innerProps.event.title || createElement(Fragment, null, "\u00A0")))); 12275 } 12276 12277 var TableCellMoreLink = /** @class */ (function (_super) { 12278 __extends(TableCellMoreLink, _super); 12279 function TableCellMoreLink() { 12280 var _this = _super !== null && _super.apply(this, arguments) || this; 12281 _this.compileSegs = memoize(compileSegs); 12282 return _this; 12283 } 12284 TableCellMoreLink.prototype.render = function () { 12285 var props = this.props; 12286 var _a = this.compileSegs(props.singlePlacements), allSegs = _a.allSegs, invisibleSegs = _a.invisibleSegs; 12287 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 () { 12288 var isForcedInvisible = (props.eventDrag ? props.eventDrag.affectedInstances : null) || 12289 (props.eventResize ? props.eventResize.affectedInstances : null) || 12290 {}; 12291 return (createElement(Fragment, null, allSegs.map(function (seg) { 12292 var instanceId = seg.eventRange.instance.instanceId; 12293 return (createElement("div", { className: "fc-daygrid-event-harness", key: instanceId, style: { 12294 visibility: isForcedInvisible[instanceId] ? 'hidden' : '', 12295 } }, 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)))))); 12296 }))); 12297 } }, 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)); })); 12298 }; 12299 return TableCellMoreLink; 12300 }(BaseComponent)); 12301 function compileSegs(singlePlacements) { 12302 var allSegs = []; 12303 var invisibleSegs = []; 12304 for (var _i = 0, singlePlacements_1 = singlePlacements; _i < singlePlacements_1.length; _i++) { 12305 var placement = singlePlacements_1[_i]; 12306 allSegs.push(placement.seg); 12307 if (!placement.isVisible) { 12308 invisibleSegs.push(placement.seg); 12309 } 12310 } 12311 return { allSegs: allSegs, invisibleSegs: invisibleSegs }; 12312 } 12313 12314 var DEFAULT_WEEK_NUM_FORMAT$1 = createFormatter({ week: 'narrow' }); 12315 var TableCell = /** @class */ (function (_super) { 12316 __extends(TableCell, _super); 12317 function TableCell() { 12318 var _this = _super !== null && _super.apply(this, arguments) || this; 12319 _this.rootElRef = createRef(); 12320 _this.state = { 12321 dayNumberId: getUniqueDomId(), 12322 }; 12323 _this.handleRootEl = function (el) { 12324 setRef(_this.rootElRef, el); 12325 setRef(_this.props.elRef, el); 12326 }; 12327 return _this; 12328 } 12329 TableCell.prototype.render = function () {
12330 var _a = this, context = _a.context, props = _a.props, state = _a.state, rootElRef = _a.rootElRef; 12331 var date = props.date, dateProfile = props.dateProfile; 12332 var navLinkAttrs = buildNavLinkAttrs(context, date, 'week'); 12333 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 } : {})), 12334 createElement("div", { className: "fc-daygrid-day-frame fc-scrollgrid-sync-inner", ref: props.innerElRef /* different from hook system! RENAME */ }, 12335 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)); })), 12336 !isDisabled && (createElement(TableCellTop, { date: date, dateProfile: dateProfile, showDayNumber: props.showDayNumber, dayNumberId: state.dayNumberId, forceDayTop: props.forceDayTop, todayRange: props.todayRange, extraHookProps: props.extraHookProps })), 12337 createElement("div", { className: "fc-daygrid-day-events", ref: props.fgContentElRef }, 12338 props.fgContent, 12339 createElement("div", { className: "fc-daygrid-day-bottom", style: { marginTop: props.moreMarginTop } }, 12340 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 }))), 12341 createElement("div", { className: "fc-daygrid-day-bg" }, props.bgContent)))); })); 12342 }; 12343 return TableCell; 12344 }(DateComponent)); 12345 12346 function computeFgSegPlacement(segs, // assumed already sorted 12347 dayMaxEvents, dayMaxEventRows, strictOrder, eventInstanceHeights, maxContentHeight, cells) { 12348 var hierarchy = new DayGridSegHierarchy(); 12349 hierarchy.allowReslicing = true; 12350 hierarchy.strictOrder = strictOrder; 12351 if (dayMaxEvents === true || dayMaxEventRows === true) { 12352 hierarchy.maxCoord = maxContentHeight; 12353 hierarchy.hiddenConsumes = true; 12354 } 12355 else if (typeof dayMaxEvents === 'number') { 12356 hierarchy.maxStackCnt = dayMaxEvents; 12357 } 12358 else if (typeof dayMaxEventRows === 'number') { 12359 hierarchy.maxStackCnt = dayMaxEventRows; 12360 hierarchy.hiddenConsumes = true; 12361 } 12362 // create segInputs only for segs with known heights 12363 var segInputs = []; 12364 var unknownHeightSegs = []; 12365 for (var i = 0; i < segs.length; i += 1) { 12366 var seg = segs[i]; 12367 var instanceId = seg.eventRange.instance.instanceId; 12368 var eventHeight = eventInstanceHeights[instanceId]; 12369 if (eventHeight != null) { 12370 segInputs.push({ 12371 index: i, 12372 thickness: eventHeight, 12373 span: { 12374 start: seg.firstCol, 12375 end: seg.lastCol + 1, 12376 }, 12377 }); 12378 } 12379 else { 12380 unknownHeightSegs.push(seg); 12381 } 12382 } 12383 var hiddenEntries = hierarchy.addSegs(segInputs); 12384 var segRects = hierarchy.toRects(); 12385 var _a = placeRects(segRects, segs, cells), singleColPlacements = _a.singleColPlacements, multiColPlacements = _a.multiColPlacements, leftoverMargins = _a.leftoverMargins; 12386 var moreCnts = []; 12387 var moreMarginTops = []; 12388 // add segs with unknown heights 12389 for (var _i = 0, unknownHeightSegs_1 = unknownHeightSegs; _i < unknownHeightSegs_1.length; _i++) { 12390 var seg = unknownHeightSegs_1[_i]; 12391 multiColPlacements[seg.firstCol].push({ 12392 seg: seg, 12393 isVisible: false, 12394 isAbsolute: true, 12395 absoluteTop: 0, 12396 marginTop: 0, 12397 });
12398 for (var col = seg.firstCol; col <= seg.lastCol; col += 1) { 12399 singleColPlacements[col].push({ 12400 seg: resliceSeg(seg, col, col + 1, cells), 12401 isVisible: false, 12402 isAbsolute: false, 12403 absoluteTop: 0, 12404 marginTop: 0, 12405 }); 12406 } 12407 } 12408 // add the hidden entries 12409 for (var col = 0; col < cells.length; col += 1) { 12410 moreCnts.push(0); 12411 } 12412 for (var _b = 0, hiddenEntries_1 = hiddenEntries; _b < hiddenEntries_1.length; _b++) { 12413 var hiddenEntry = hiddenEntries_1[_b]; 12414 var seg = segs[hiddenEntry.index]; 12415 var hiddenSpan = hiddenEntry.span; 12416 multiColPlacements[hiddenSpan.start].push({ 12417 seg: resliceSeg(seg, hiddenSpan.start, hiddenSpan.end, cells), 12418 isVisible: false, 12419 isAbsolute: true, 12420 absoluteTop: 0, 12421 marginTop: 0, 12422 }); 12423 for (var col = hiddenSpan.start; col < hiddenSpan.end; col += 1) { 12424 moreCnts[col] += 1; 12425 singleColPlacements[col].push({ 12426 seg: resliceSeg(seg, col, col + 1, cells), 12427 isVisible: false, 12428 isAbsolute: false, 12429 absoluteTop: 0, 12430 marginTop: 0, 12431 }); 12432 } 12433 } 12434 // deal with leftover margins 12435 for (var col = 0; col < cells.length; col += 1) { 12436 moreMarginTops.push(leftoverMargins[col]); 12437 } 12438 return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, moreCnts: moreCnts, moreMarginTops: moreMarginTops }; 12439 } 12440 // rects ordered by top coord, then left 12441 function placeRects(allRects, segs, cells) { 12442 var rectsByEachCol = groupRectsByEachCol(allRects, cells.length); 12443 var singleColPlacements = []; 12444 var multiColPlacements = []; 12445 var leftoverMargins = []; 12446 for (var col = 0; col < cells.length; col += 1) { 12447 var rects = rectsByEachCol[col]; 12448 // compute all static segs in singlePlacements 12449 var singlePlacements = []; 12450 var currentHeight = 0; 12451 var currentMarginTop = 0; 12452 for (var _i = 0, rects_1 = rects; _i < rects_1.length; _i++) { 12453 var rect = rects_1[_i]; 12454 var seg = segs[rect.index]; 12455 singlePlacements.push({ 12456 seg: resliceSeg(seg, col, col + 1, cells), 12457 isVisible: true, 12458 isAbsolute: false, 12459 absoluteTop: rect.levelCoord, 12460 marginTop: rect.levelCoord - currentHeight, 12461 }); 12462 currentHeight = rect.levelCoord + rect.thickness; 12463 } 12464 // compute mixed static/absolute segs in multiPlacements 12465 var multiPlacements = []; 12466 currentHeight = 0; 12467 currentMarginTop = 0; 12468 for (var _a = 0, rects_2 = rects; _a < rects_2.length; _a++) { 12469 var rect = rects_2[_a]; 12470 var seg = segs[rect.index]; 12471 var isAbsolute = rect.span.end - rect.span.start > 1; // multi-column? 12472 var isFirstCol = rect.span.start === col; 12473 currentMarginTop += rect.levelCoord - currentHeight; // amount of space since bottom of previous seg 12474 currentHeight = rect.levelCoord + rect.thickness; // height will now be bottom of current seg 12475 if (isAbsolute) { 12476 currentMarginTop += rect.thickness; 12477 if (isFirstCol) { 12478 multiPlacements.push({ 12479 seg: resliceSeg(seg, rect.span.start, rect.span.end, cells), 12480 isVisible: true, 12481 isAbsolute: true, 12482 absoluteTop: rect.levelCoord, 12483 marginTop: 0, 12484 }); 12485 } 12486 } 12487 else if (isFirstCol) { 12488 multiPlacements.push({ 12489 seg: resliceSeg(seg, rect.span.start, rect.span.end, cells), 12490 isVisible: true, 12491 isAbsolute: false, 12492 absoluteTop: rect.levelCoord, 12493 marginTop: currentMarginTop, // claim the margin 12494 }); 12495 currentMarginTop = 0; 12496 } 12497 } 12498 singleColPlacements.push(singlePlacements); 12499 multiColPlacements.push(multiPlacements); 12500 leftoverMargins.push(currentMarginTop); 12501 } 12502 return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, leftoverMargins: leftoverMargins }; 12503 } 12504 function groupRectsByEachCol(rects, colCnt) { 12505 var rectsByEachCol = []; 12506 for (var col = 0; col < colCnt; col += 1) { 12507 rectsByEachCol.push([]); 12508 } 12509 for (var _i = 0, rects_3 = rects; _i < rects_3.length; _i++) { 12510 var rect = rects_3[_i]; 12511 for (var col = rect.span.start; col < rect.span.end; col += 1) { 12512 rectsByEachCol[col].push(rect); 12513 } 12514 } 12515 return rectsByEachCol; 12516 } 12517 function resliceSeg(seg, spanStart, spanEnd, cells) { 12518 if (seg.firstCol === spanStart && seg.lastCol === spanEnd - 1) { 12519 return seg; 12520 } 12521 var eventRange = seg.eventRange; 12522 var origRange = eventRange.range; 12523 var slicedRange = intersectRanges(origRange, { 12524 start: cells[spanStart].date, 12525 end: addDays(cells[spanEnd - 1].date, 1), 12526 }); 12527 return __assign(__assign({}, seg), { firstCol: spanStart, lastCol: spanEnd - 1, eventRange: { 12528 def: eventRange.def, 12529 ui: __assign(__assign({}, eventRange.ui), { durationEditable: false }), 12530 instance: eventRange.instance, 12531 range: slicedRange, 12532 }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() }); 12533 } 12534 var DayGridSegHierarchy = /** @class */ (function (_super) { 12535 __extends(DayGridSegHierarchy, _super); 12536 function DayGridSegHierarchy() { 12537 var _this = _super !== null && _super.apply(this, arguments) || this; 12538 // config 12539 _this.hiddenConsumes = false; 12540 // allows us to keep hidden entries in the hierarchy so they take up space 12541 _this.forceHidden = {}; 12542 return _this; 12543 } 12544 DayGridSegHierarchy.prototype.addSegs = function (segInputs) { 12545 var _this = this; 12546 var hiddenSegs = _super.prototype.addSegs.call(this, segInputs); 12547 var entriesByLevel = this.entriesByLevel; 12548 var excludeHidden = function (entry) { return !_this.forceHidden[buildEntryKey(entry)]; }; 12549 // remove the forced-hidden segs 12550 for (var level = 0; level < entriesByLevel.length; level += 1) {
12551 entriesByLevel[level] = entriesByLevel[level].filter(excludeHidden); 12552 } 12553 return hiddenSegs; 12554 }; 12555 DayGridSegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) { 12556 var _a = this, entriesByLevel = _a.entriesByLevel, forceHidden = _a.forceHidden; 12557 var touchingEntry = insertion.touchingEntry, touchingLevel = insertion.touchingLevel, touchingLateral = insertion.touchingLateral; 12558 if (this.hiddenConsumes && touchingEntry) { 12559 var touchingEntryId = buildEntryKey(touchingEntry); 12560 // if not already hidden 12561 if (!forceHidden[touchingEntryId]) { 12562 if (this.allowReslicing) { 12563 var placeholderEntry = __assign(__assign({}, touchingEntry), { span: intersectSpans(touchingEntry.span, entry.span) }); 12564 var placeholderEntryId = buildEntryKey(placeholderEntry); 12565 forceHidden[placeholderEntryId] = true; 12566 entriesByLevel[touchingLevel][touchingLateral] = placeholderEntry; // replace touchingEntry with our placeholder 12567 this.splitEntry(touchingEntry, entry, hiddenEntries); // split up the touchingEntry, reinsert it 12568 } 12569 else { 12570 forceHidden[touchingEntryId] = true; 12571 hiddenEntries.push(touchingEntry); 12572 } 12573 } 12574 } 12575 return _super.prototype.handleInvalidInsertion.call(this, insertion, entry, hiddenEntries); 12576 }; 12577 return DayGridSegHierarchy; 12578 }(SegHierarchy)); 12579 12580 var TableRow = /** @class */ (function (_super) { 12581 __extends(TableRow, _super); 12582 function TableRow() { 12583 var _this = _super !== null && _super.apply(this, arguments) || this; 12584 _this.cellElRefs = new RefMap(); // the <td> 12585 _this.frameElRefs = new RefMap(); // the fc-daygrid-day-frame 12586 _this.fgElRefs = new RefMap(); // the fc-daygrid-day-events 12587 _this.segHarnessRefs = new RefMap(); // indexed by "instanceId:firstCol" 12588 _this.rootElRef = createRef(); 12589 _this.state = { 12590 framePositions: null, 12591 maxContentHeight: null, 12592 eventInstanceHeights: {}, 12593 }; 12594 return _this; 12595 } 12596 TableRow.prototype.render = function () { 12597 var _this = this; 12598 var _a = this, props = _a.props, state = _a.state, context = _a.context; 12599 var options = context.options; 12600 var colCnt = props.cells.length; 12601 var businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt); 12602 var bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt); 12603 var highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt); 12604 var mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt); 12605 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; 12606 var isForcedInvisible = // TODO: messy way to compute this 12607 (props.eventDrag && props.eventDrag.affectedInstances) || 12608 (props.eventResize && props.eventResize.affectedInstances) || 12609 {}; 12610 return (createElement("tr", { ref: this.rootElRef, role: "row" }, 12611 props.renderIntro && props.renderIntro(), 12612 props.cells.map(function (cell, col) { 12613 var normalFgNodes = _this.renderFgSegs(col, props.forPrint ? singleColPlacements[col] : multiColPlacements[col], props.todayRange, isForcedInvisible); 12614 var mirrorFgNodes = _this.renderFgSegs(col, buildMirrorPlacements(mirrorSegsByCol[col], multiColPlacements), props.todayRange, {}, Boolean(props.eventDrag), Boolean(props.eventResize), false); 12615 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 12616 createElement(Fragment, null, 12617 createElement(Fragment, null, normalFgNodes), 12618 createElement(Fragment, null, mirrorFgNodes))), bgContent: ( // Fragment scopes the keys 12619 createElement(Fragment, null, 12620 _this.renderFillSegs(highlightSegsByCol[col], 'highlight'), 12621 _this.renderFillSegs(businessHoursByCol[col], 'non-business'), 12622 _this.renderFillSegs(bgEventSegsByCol[col], 'bg-event'))) })); 12623 }))); 12624 }; 12625 TableRow.prototype.componentDidMount = function () { 12626 this.updateSizing(true); 12627 }; 12628 TableRow.prototype.componentDidUpdate = function (prevProps, prevState) { 12629 var currentProps = this.props; 12630 this.updateSizing(!isPropsEqual(prevProps, currentProps)); 12631 }; 12632 TableRow.prototype.getHighlightSegs = function () { 12633 var props = this.props; 12634 if (props.eventDrag && props.eventDrag.segs.length) { // messy check 12635 return props.eventDrag.segs; 12636 } 12637 if (props.eventResize && props.eventResize.segs.length) { // messy check 12638 return props.eventResize.segs; 12639 } 12640 return props.dateSelectionSegs; 12641 }; 12642 TableRow.prototype.getMirrorSegs = function () { 12643 var props = this.props; 12644 if (props.eventResize && props.eventResize.segs.length) { // messy check 12645 return props.eventResize.segs; 12646 } 12647 return []; 12648 }; 12649 TableRow.prototype.renderFgSegs = function (col, segPlacements, todayRange, isForcedInvisible, isDragging, isResizing, isDateSelecting) { 12650 var context = this.context; 12651 var eventSelection = this.props.eventSelection; 12652 var framePositions = this.state.framePositions; 12653 var defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1 12654 var isMirror = isDragging || isResizing || isDateSelecting; 12655 var nodes = []; 12656 if (framePositions) { 12657 for (var _i = 0, segPlacements_1 = segPlacements; _i < segPlacements_1.length; _i++) { 12658 var placement = segPlacements_1[_i]; 12659 var seg = placement.seg; 12660 var instanceId = seg.eventRange.instance.instanceId; 12661 var key = instanceId + ':' + col; 12662 var isVisible = placement.isVisible && !isForcedInvisible[instanceId];
12663 var isAbsolute = placement.isAbsolute; 12664 var left = ''; 12665 var right = ''; 12666 if (isAbsolute) { 12667 if (context.isRtl) { 12668 right = 0; 12669 left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol]; 12670 } 12671 else { 12672 left = 0; 12673 right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol]; 12674 } 12675 } 12676 /* 12677 known bug: events that are force to be list-item but span multiple days still take up space in later columns 12678 todo: in print view, for multi-day events, don't display title within non-start/end segs 12679 */ 12680 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: { 12681 visibility: isVisible ? '' : 'hidden', 12682 marginTop: isAbsolute ? '' : placement.marginTop, 12683 top: isAbsolute ? placement.absoluteTop : '', 12684 left: left, 12685 right: right, 12686 } }, 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)))))); 12687 } 12688 } 12689 return nodes; 12690 }; 12691 TableRow.prototype.renderFillSegs = function (segs, fillType) { 12692 var isRtl = this.context.isRtl; 12693 var todayRange = this.props.todayRange; 12694 var framePositions = this.state.framePositions; 12695 var nodes = []; 12696 if (framePositions) { 12697 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 12698 var seg = segs_1[_i]; 12699 var leftRightCss = isRtl ? { 12700 right: 0, 12701 left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol], 12702 } : { 12703 left: 0, 12704 right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol], 12705 }; 12706 nodes.push(createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-daygrid-bg-harness", style: leftRightCss }, fillType === 'bg-event' ? 12707 createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, todayRange))) : 12708 renderFill(fillType))); 12709 } 12710 } 12711 return createElement.apply(void 0, __spreadArray([Fragment, {}], nodes)); 12712 }; 12713 TableRow.prototype.updateSizing = function (isExternalSizingChange) { 12714 var _a = this, props = _a.props, frameElRefs = _a.frameElRefs; 12715 if (!props.forPrint && 12716 props.clientWidth !== null // positioning ready? 12717 ) { 12718 if (isExternalSizingChange) { 12719 var frameEls = props.cells.map(function (cell) { return frameElRefs.currentMap[cell.key]; }); 12720 if (frameEls.length) { 12721 var originEl = this.rootElRef.current; 12722 this.setState({ 12723 framePositions: new PositionCache(originEl, frameEls, true, // isHorizontal 12724 false), 12725 }); 12726 } 12727 } 12728 var oldInstanceHeights = this.state.eventInstanceHeights; 12729 var newInstanceHeights = this.queryEventInstanceHeights();
12730 var limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true; 12731 this.safeSetState({ 12732 // HACK to prevent oscillations of events being shown/hidden from max-event-rows 12733 // Essentially, once you compute an element's height, never null-out. 12734 // TODO: always display all events, as visibility:hidden? 12735 eventInstanceHeights: __assign(__assign({}, oldInstanceHeights), newInstanceHeights), 12736 maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null, 12737 }); 12738 } 12739 }; 12740 TableRow.prototype.queryEventInstanceHeights = function () { 12741 var segElMap = this.segHarnessRefs.currentMap; 12742 var eventInstanceHeights = {}; 12743 // get the max height amongst instance segs 12744 for (var key in segElMap) { 12745 var height = Math.round(segElMap[key].getBoundingClientRect().height); 12746 var instanceId = key.split(':')[0]; // deconstruct how renderFgSegs makes the key 12747 eventInstanceHeights[instanceId] = Math.max(eventInstanceHeights[instanceId] || 0, height); 12748 } 12749 return eventInstanceHeights; 12750 }; 12751 TableRow.prototype.computeMaxContentHeight = function () { 12752 var firstKey = this.props.cells[0].key; 12753 var cellEl = this.cellElRefs.currentMap[firstKey]; 12754 var fcContainerEl = this.fgElRefs.currentMap[firstKey]; 12755 return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top; 12756 }; 12757 TableRow.prototype.getCellEls = function () { 12758 var elMap = this.cellElRefs.currentMap; 12759 return this.props.cells.map(function (cell) { return elMap[cell.key]; }); 12760 }; 12761 return TableRow; 12762 }(DateComponent)); 12763 TableRow.addStateEquality({ 12764 eventInstanceHeights: isPropsEqual, 12765 }); 12766 function buildMirrorPlacements(mirrorSegs, colPlacements) { 12767 if (!mirrorSegs.length) { 12768 return []; 12769 } 12770 var topsByInstanceId = buildAbsoluteTopHash(colPlacements); // TODO: cache this at first render? 12771 return mirrorSegs.map(function (seg) { return ({ 12772 seg: seg, 12773 isVisible: true, 12774 isAbsolute: true, 12775 absoluteTop: topsByInstanceId[seg.eventRange.instance.instanceId], 12776 marginTop: 0, 12777 }); }); 12778 } 12779 function buildAbsoluteTopHash(colPlacements) { 12780 var topsByInstanceId = {}; 12781 for (var _i = 0, colPlacements_1 = colPlacements; _i < colPlacements_1.length; _i++) { 12782 var placements = colPlacements_1[_i]; 12783 for (var _a = 0, placements_1 = placements; _a < placements_1.length; _a++) { 12784 var placement = placements_1[_a]; 12785 topsByInstanceId[placement.seg.eventRange.instance.instanceId] = placement.absoluteTop; 12786 } 12787 } 12788 return topsByInstanceId; 12789 } 12790 12791 var Table = /** @class */ (function (_super) { 12792 __extends(Table, _super); 12793 function Table() { 12794 var _this = _super !== null && _super.apply(this, arguments) || this; 12795 _this.splitBusinessHourSegs = memoize(splitSegsByRow); 12796 _this.splitBgEventSegs = memoize(splitSegsByRow); 12797 _this.splitFgEventSegs = memoize(splitSegsByRow); 12798 _this.splitDateSelectionSegs = memoize(splitSegsByRow); 12799 _this.splitEventDrag = memoize(splitInteractionByRow); 12800 _this.splitEventResize = memoize(splitInteractionByRow); 12801 _this.rowRefs = new RefMap(); 12802 _this.handleRootEl = function (rootEl) { 12803 _this.rootEl = rootEl; 12804 if (rootEl) { 12805 _this.context.registerInteractiveComponent(_this, { 12806 el: rootEl, 12807 isHitComboAllowed: _this.props.isHitComboAllowed, 12808 }); 12809 } 12810 else { 12811 _this.context.unregisterInteractiveComponent(_this); 12812 } 12813 }; 12814 return _this; 12815 } 12816 Table.prototype.render = function () { 12817 var _this = this; 12818 var props = this.props; 12819 var dateProfile = props.dateProfile, dayMaxEventRows = props.dayMaxEventRows, dayMaxEvents = props.dayMaxEvents, expandRows = props.expandRows; 12820 var rowCnt = props.cells.length; 12821 var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt); 12822 var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt); 12823 var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt); 12824 var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt); 12825 var eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt); 12826 var eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt); 12827 var limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true; 12828 // if rows can't expand to fill fixed height, can't do balanced-height event limit 12829 // TODO: best place to normalize these options? 12830 if (limitViaBalanced && !expandRows) { 12831 limitViaBalanced = false; 12832 dayMaxEventRows = null; 12833 dayMaxEvents = null; 12834 } 12835 var classNames = [
12836 'fc-daygrid-body', 12837 limitViaBalanced ? 'fc-daygrid-body-balanced' : 'fc-daygrid-body-unbalanced', 12838 expandRows ? '' : 'fc-daygrid-body-natural', // will height of one row depend on the others? 12839 ]; 12840 return (createElement("div", { className: classNames.join(' '), ref: this.handleRootEl, style: { 12841 // these props are important to give this wrapper correct dimensions for interactions 12842 // TODO: if we set it here, can we avoid giving to inner tables? 12843 width: props.clientWidth, 12844 minWidth: props.tableMinWidth, 12845 } }, 12846 createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement(Fragment, null, 12847 createElement("table", { role: "presentation", className: "fc-scrollgrid-sync-table", style: { 12848 width: props.clientWidth, 12849 minWidth: props.tableMinWidth, 12850 height: expandRows ? props.clientHeight : '', 12851 } }, 12852 props.colGroupNode, 12853 createElement("tbody", { role: "presentation" }, props.cells.map(function (cells, row) { return (createElement(TableRow, { ref: _this.rowRefs.createRef(row), key: cells.length 12854 ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */ 12855 : row // in case there are no cells (like when resource view is loading) 12856 , 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 })); }))))); }))); 12857 }; 12858 // Hit System 12859 // ---------------------------------------------------------------------------------------------------- 12860 Table.prototype.prepareHits = function () { 12861 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 12862 false, true); 12863 this.colPositions = new PositionCache(this.rootEl, this.rowRefs.currentMap[0].getCellEls(), // cell els in first row 12864 true, // horizontal 12865 false); 12866 }; 12867 Table.prototype.queryHit = function (positionLeft, positionTop) { 12868 var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions; 12869 var col = colPositions.leftToIndex(positionLeft); 12870 var row = rowPositions.topToIndex(positionTop); 12871 if (row != null && col != null) { 12872 var cell = this.props.cells[row][col]; 12873 return { 12874 dateProfile: this.props.dateProfile, 12875 dateSpan: __assign({ range: this.getCellRange(row, col), allDay: true }, cell.extraDateSpan), 12876 dayEl: this.getCellEl(row, col), 12877 rect: { 12878 left: colPositions.lefts[col], 12879 right: colPositions.rights[col], 12880 top: rowPositions.tops[row], 12881 bottom: rowPositions.bottoms[row], 12882 }, 12883 layer: 0, 12884 }; 12885 } 12886 return null; 12887 }; 12888 Table.prototype.getCellEl = function (row, col) { 12889 return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal 12890 }; 12891 Table.prototype.getCellRange = function (row, col) { 12892 var start = this.props.cells[row][col].date; 12893 var end = addDays(start, 1); 12894 return { start: start, end: end }; 12895 }; 12896 return Table; 12897 }(DateComponent)); 12898 function isSegAllDay(seg) { 12899 return seg.eventRange.def.allDay; 12900 } 12901 12902 var DayTableSlicer = /** @class */ (function (_super) { 12903 __extends(DayTableSlicer, _super); 12904 function DayTableSlicer() { 12905 var _this = _super !== null && _super.apply(this, arguments) || this; 12906 _this.forceDayIfListItem = true; 12907 return _this; 12908 } 12909 DayTableSlicer.prototype.sliceRange = function (dateRange, dayTableModel) { 12910 return dayTableModel.sliceRange(dateRange); 12911 }; 12912 return DayTableSlicer; 12913 }(Slicer));
12914 12915 var DayTable = /** @class */ (function (_super) { 12916 __extends(DayTable, _super); 12917 function DayTable() { 12918 var _this = _super !== null && _super.apply(this, arguments) || this; 12919 _this.slicer = new DayTableSlicer(); 12920 _this.tableRef = createRef(); 12921 return _this; 12922 } 12923 DayTable.prototype.render = function () { 12924 var _a = this, props = _a.props, context = _a.context; 12925 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 }))); 12926 }; 12927 return DayTable; 12928 }(DateComponent)); 12929 12930 var DayTableView = /** @class */ (function (_super) { 12931 __extends(DayTableView, _super); 12932 function DayTableView() { 12933 var _this = _super !== null && _super.apply(this, arguments) || this; 12934 _this.buildDayTableModel = memoize(buildDayTableModel); 12935 _this.headerRef = createRef(); 12936 _this.tableRef = createRef(); 12937 return _this; 12938 } 12939 DayTableView.prototype.render = function () { 12940 var _this = this; 12941 var _a = this.context, options = _a.options, dateProfileGenerator = _a.dateProfileGenerator; 12942 var props = this.props; 12943 var dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator); 12944 var headerContent = options.dayHeaders && (createElement(DayHeader, { ref: this.headerRef, dateProfile: props.dateProfile, dates: dayTableModel.headerDates, datesRepDistinctDays: dayTableModel.rowCnt === 1 })); 12945 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 })); }; 12946 return options.dayMinWidth 12947 ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth) 12948 : this.renderSimpleLayout(headerContent, bodyContent); 12949 }; 12950 return DayTableView; 12951 }(TableView)); 12952 function buildDayTableModel(dateProfile, dateProfileGenerator) {
12953 var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator); 12954 return new DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit)); 12955 } 12956 12957 var TableDateProfileGenerator = /** @class */ (function (_super) { 12958 __extends(TableDateProfileGenerator, _super); 12959 function TableDateProfileGenerator() { 12960 return _super !== null && _super.apply(this, arguments) || this; 12961 } 12962 // Computes the date range that will be rendered. 12963 TableDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) { 12964 var dateEnv = this.props.dateEnv; 12965 var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay); 12966 var start = renderRange.start; 12967 var end = renderRange.end; 12968 var endOfWeek; 12969 // year and month views should be aligned with weeks. this is already done for week 12970 if (/^(year|month)$/.test(currentRangeUnit)) { 12971 start = dateEnv.startOfWeek(start); 12972 // make end-of-week if not already 12973 endOfWeek = dateEnv.startOfWeek(end); 12974 if (endOfWeek.valueOf() !== end.valueOf()) { 12975 end = addWeeks(endOfWeek, 1); 12976 } 12977 } 12978 // ensure 6 weeks 12979 if (this.props.monthMode && 12980 this.props.fixedWeekCount) { 12981 var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays 12982 diffWeeks(start, end)); 12983 end = addWeeks(end, 6 - rowCnt); 12984 } 12985 return { start: start, end: end }; 12986 }; 12987 return TableDateProfileGenerator; 12988 }(DateProfileGenerator)); 12989 12990 var dayGridPlugin = createPlugin({ 12991 initialView: 'dayGridMonth', 12992 views: { 12993 dayGrid: { 12994 component: DayTableView, 12995 dateProfileGeneratorClass: TableDateProfileGenerator, 12996 }, 12997 dayGridDay: { 12998 type: 'dayGrid', 12999 duration: { days: 1 }, 13000 }, 13001 dayGridWeek: { 13002 type: 'dayGrid', 13003 duration: { weeks: 1 }, 13004 }, 13005 dayGridMonth: { 13006 type: 'dayGrid', 13007 duration: { months: 1 }, 13008 monthMode: true, 13009 fixedWeekCount: true, 13010 }, 13011 }, 13012 }); 13013 13014 var AllDaySplitter = /** @class */ (function (_super) { 13015 __extends(AllDaySplitter, _super); 13016 function AllDaySplitter() { 13017 return _super !== null && _super.apply(this, arguments) || this; 13018 } 13019 AllDaySplitter.prototype.getKeyInfo = function () { 13020 return { 13021 allDay: {}, 13022 timed: {}, 13023 }; 13024 }; 13025 AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) { 13026 if (dateSpan.allDay) { 13027 return ['allDay']; 13028 } 13029 return ['timed']; 13030 }; 13031 AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) { 13032 if (!eventDef.allDay) { 13033 return ['timed']; 13034 } 13035 if (hasBgRendering(eventDef)) { 13036 return ['timed', 'allDay']; 13037 } 13038 return ['allDay']; 13039 }; 13040 return AllDaySplitter; 13041 }(Splitter)); 13042 13043 var DEFAULT_SLAT_LABEL_FORMAT = createFormatter({ 13044 hour: 'numeric', 13045 minute: '2-digit', 13046 omitZeroMinute: true, 13047 meridiem: 'short', 13048 }); 13049 function TimeColsAxisCell(props) { 13050 var classNames = [ 13051 'fc-timegrid-slot', 13052 'fc-timegrid-slot-label', 13053 props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor', 13054 ]; 13055 return (createElement(ViewContextType.Consumer, null, function (context) { 13056 if (!props.isLabeled) { 13057 return (createElement("td", { className: classNames.join(' '), "data-time": props.isoTimeStr })); 13058 } 13059 var dateEnv = context.dateEnv, options = context.options, viewApi = context.viewApi; 13060 var labelFormat = // TODO: fully pre-parse 13061 options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT : 13062 Array.isArray(options.slotLabelFormat) ? createFormatter(options.slotLabelFormat[0]) : 13063 createFormatter(options.slotLabelFormat); 13064 var hookProps = { 13065 level: 0, 13066 time: props.time, 13067 date: dateEnv.toDate(props.date), 13068 view: viewApi, 13069 text: dateEnv.format(props.date, labelFormat), 13070 }; 13071 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
13071oncat(customClassNames).join(' '), "data-time": props.isoTimeStr }, 13072 createElement("div", { className: "fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame" }, 13073 createElement("div", { className: "fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion", ref: innerElRef }, innerContent)))); })); 13074 })); 13075 } 13076 function renderInnerContent$1(props) { 13077 return props.text; 13078 } 13079 13080 var TimeBodyAxis = /** @class */ (function (_super) { 13081 __extends(TimeBodyAxis, _super); 13082 function TimeBodyAxis() { 13083 return _super !== null && _super.apply(this, arguments) || this; 13084 } 13085 TimeBodyAxis.prototype.render = function () { 13086 return this.props.slatMetas.map(function (slatMeta) { return (createElement("tr", { key: slatMeta.key }, 13087 createElement(TimeColsAxisCell, __assign({}, slatMeta)))); }); 13088 }; 13089 return TimeBodyAxis; 13090 }(BaseComponent)); 13091 13092 var DEFAULT_WEEK_NUM_FORMAT = createFormatter({ week: 'short' }); 13093 var AUTO_ALL_DAY_MAX_EVENT_ROWS = 5; 13094 var TimeColsView = /** @class */ (function (_super) { 13095 __extends(TimeColsView, _super); 13096 function TimeColsView() { 13097 var _this = _super !== null && _super.apply(this, arguments) || this; 13098 _this.allDaySplitter = new AllDaySplitter(); // for use by subclasses 13099 _this.headerElRef = createRef(); 13100 _this.rootElRef = createRef(); 13101 _this.scrollerElRef = createRef(); 13102 _this.state = { 13103 slatCoords: null, 13104 }; 13105 _this.handleScrollTopRequest = function (scrollTop) { 13106 var scrollerEl = _this.scrollerElRef.current; 13107 if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer 13108 scrollerEl.scrollTop = scrollTop; 13109 } 13110 }; 13111 /* Header Render Methods 13112 ------------------------------------------------------------------------------------------------------------------*/ 13113 _this.renderHeadAxis = function (rowKey, frameHeight) { 13114 if (frameHeight === void 0) { frameHeight = ''; } 13115 var options = _this.context.options; 13116 var dateProfile = _this.props.dateProfile; 13117 var range = dateProfile.renderRange; 13118 var dayCnt = diffDays(range.start, range.end); 13119 var navLinkAttrs = (dayCnt === 1) // only do in day views (to avoid doing in week views that dont need it) 13120 ? buildNavLinkAttrs(_this.context, range.start, 'week') 13121 : {}; 13122 if (options.weekNumbers && rowKey === 'day') { 13123 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: [ 13124 'fc-timegrid-axis', 13125 'fc-scrollgrid-shrink', 13126 ].concat(classNames).join(' ') }, 13127 createElement("div", { className: "fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid", style: { height: frameHeight } }, 13128 createElement("a", __assign({ ref: innerElRef, className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner" }, navLinkAttrs), innerContent)))); })); 13129 } 13130 return (createElement("th", { "aria-hidden": true, className: "fc-timegrid-axis" }, 13131 createElement("div", { className: "fc-timegrid-axis-frame", style: { height: frameHeight } }))); 13132 }; 13133 /* Table Component Render Methods 13134 ------------------------------------------------------------------------------------------------------------------*/ 13135 // only a one-way height sync. we don't send the axis inner-content height to the DayGrid, 13136 // but DayGrid still needs to have classNames on inner elements in order to measure. 13137 _this.renderTableRowAxis = function (rowHeight) { 13138 var _a = _this.context, options = _a.options, viewApi = _a.viewApi; 13139 var hookProps = { 13140 text: options.allDayText, 13141 view: viewApi, 13142 }; 13143 return ( 13144 // TODO: make reusable hook. used in list view too 13145 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: [ 13146 'fc-timegrid-axis', 13147 'fc-scrollgrid-shrink', 13148 ].concat(classNames).join(' ') }, 13149 createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame' + (rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : ''), style: { height: rowHeight } }, 13150 createElement("span", { className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner", ref: innerElRef }, innerContent)))); })); 13151 }; 13152 _this.handleSlatCoords = function (slatCoords) {
13153 _this.setState({ slatCoords: slatCoords }); 13154 }; 13155 return _this; 13156 } 13157 // rendering 13158 // ---------------------------------------------------------------------------------------------------- 13159 TimeColsView.prototype.renderSimpleLayout = function (headerRowContent, allDayContent, timeContent) { 13160 var _a = this, context = _a.context, props = _a.props; 13161 var sections = []; 13162 var stickyHeaderDates = getStickyHeaderDates(context.options); 13163 if (headerRowContent) { 13164 sections.push({ 13165 type: 'header', 13166 key: 'header', 13167 isSticky: stickyHeaderDates, 13168 chunk: { 13169 elRef: this.headerElRef, 13170 tableClassName: 'fc-col-header', 13171 rowContent: headerRowContent, 13172 }, 13173 }); 13174 } 13175 if (allDayContent) { 13176 sections.push({ 13177 type: 'body', 13178 key: 'all-day', 13179 chunk: { content: allDayContent }, 13180 }); 13181 sections.push({ 13182 type: 'body', 13183 key: 'all-day-divider', 13184 outerContent: ( // TODO: rename to cellContent so don't need to define <tr>? 13185 createElement("tr", { role: "presentation", className: "fc-scrollgrid-section" }, 13186 createElement("td", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))), 13187 }); 13188 } 13189 sections.push({ 13190 type: 'body', 13191 key: 'body', 13192 liquid: true, 13193 expandRows: Boolean(context.options.expandRows), 13194 chunk: { 13195 scrollerElRef: this.scrollerElRef, 13196 content: timeContent, 13197 }, 13198 }); 13199 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef }, 13200 createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [{ width: 'shrink' }], sections: sections }))); })); 13201 }; 13202 TimeColsView.prototype.renderHScrollLayout = function (headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) { 13203 var _this = this; 13204 var ScrollGrid = this.context.pluginHooks.scrollGridImpl; 13205 if (!ScrollGrid) { 13206 throw new Error('No ScrollGrid implementation'); 13207 } 13208 var _a = this, context = _a.context, props = _a.props; 13209 var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options); 13210 var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options); 13211 var sections = []; 13212 if (headerRowContent) { 13213 sections.push({ 13214 type: 'header', 13215 key: 'header', 13216 isSticky: stickyHeaderDates, 13217 syncRowHeights: true, 13218 chunks: [ 13219 { 13220 key: 'axis', 13221 rowContent: function (arg) { return (createElement("tr", { role: "presentation" }, _this.renderHeadAxis('day', arg.rowSyncHeights[0]))); }, 13222 }, 13223 { 13224 key: 'cols', 13225 elRef: this.headerElRef, 13226 tableClassName: 'fc-col-header', 13227 rowContent: headerRowContent, 13228 }, 13229 ], 13230 }); 13231 } 13232 if (allDayContent) { 13233 sections.push({ 13234 type: 'body', 13235 key: 'all-day', 13236 syncRowHeights: true, 13237 chunks: [ 13238 { 13239 key: 'axis', 13240 rowContent: function (contentArg) { return (createElement("tr", { role: "presentation" }, _this.renderTableRowAxis(contentArg.rowSyncHeights[0]))); }, 13241 }, 13242 { 13243 key: 'cols', 13244 content: allDayContent, 13245 }, 13246 ], 13247 }); 13248 sections.push({ 13249 key: 'all-day-divider', 13250 type: 'body', 13251 outerContent: ( // TODO: rename to cellContent so don't need to define <tr>? 13252 createElement("tr", { role: "presentation", className: "fc-scrollgrid-section" }, 13253 createElement("td", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))), 13254 }); 13255 } 13256 var isNowIndicator = context.options.nowIndicator; 13257 sections.push({ 13258 type: 'body', 13259 key: 'body', 13260 liquid: true, 13261 expandRows: Boolean(context.options.expandRows), 13262 chunks: [ 13263 { 13264 key: 'axis', 13265 content: function (arg) { return ( 13266 // TODO: make this now-indicator arrow more DRY with TimeColsContent 13267 createElement("div", { className: "fc-timegrid-axis-chunk" }, 13268 createElement("table", { "aria-hidden": true, style: { height: arg.expandRows ? arg.clientHeight : '' } }, 13269 arg.tableColGroupNode, 13270 createElement("tbody", null, 13271 createElement(TimeBodyAxis, { slatMetas: slatMetas }))), 13272 createElement("div", { className: "fc-timegrid-now-indicator-container" }, 13273 createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, function (nowDate) { 13274 var nowIndicatorTop = isNowIndicator && 13275 slatCoords && 13276 slatCoords.safeComputeTop(nowDate); // might return void 13277 if (typeof nowIndicatorTop === 'number') { 13278 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)); })); 13279 } 13280 return null; 13281 })))); }, 13282 }, 13283 { 13284 key: 'cols', 13285 scrollerElRef: this.scrollerElRef, 13286 content: timeContent, 13287 }, 13288 ], 13289 }); 13290 if (stickyFooterScrollbar) { 13291 sections.push({ 13292 key: 'footer', 13293 type: 'footer', 13294 isSticky: true, 13295 chunks: [ 13296 { 13297 key: 'axis', 13298 content: renderScrollShim, 13299 }, 13300 { 13301 key: 'cols', 13302 content: renderScrollShim, 13303 }, 13304 ], 13305 }); 13306 } 13307 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].
13307concat(classNames).join(' '), ref: rootElRef }, 13308 createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: false, colGroups: [ 13309 { width: 'shrink', cols: [{ width: 'shrink' }] }, 13310 { cols: [{ span: colCnt, minWidth: dayMinWidth }] }, 13311 ], sections: sections }))); })); 13312 }; 13313 /* Dimensions 13314 ------------------------------------------------------------------------------------------------------------------*/ 13315 TimeColsView.prototype.getAllDayMaxEventProps = function () { 13316 var _a = this.context.options, dayMaxEvents = _a.dayMaxEvents, dayMaxEventRows = _a.dayMaxEventRows; 13317 if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto? 13318 dayMaxEvents = undefined; 13319 dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number 13320 } 13321 return { dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows }; 13322 }; 13323 return TimeColsView; 13324 }(DateComponent)); 13325 function renderAllDayInner$1(hookProps) { 13326 return hookProps.text; 13327 } 13328 13329 var TimeColsSlatsCoords = /** @class */ (function () { 13330 function TimeColsSlatsCoords(positions, dateProfile, slotDuration) { 13331 this.positions = positions; 13332 this.dateProfile = dateProfile; 13333 this.slotDuration = slotDuration; 13334 } 13335 TimeColsSlatsCoords.prototype.safeComputeTop = function (date) { 13336 var dateProfile = this.dateProfile; 13337 if (rangeContainsMarker(dateProfile.currentRange, date)) { 13338 var startOfDayDate = startOfDay(date); 13339 var timeMs = date.valueOf() - startOfDayDate.valueOf(); 13340 if (timeMs >= asRoughMs(dateProfile.slotMinTime) && 13341 timeMs < asRoughMs(dateProfile.slotMaxTime)) { 13342 return this.computeTimeTop(createDuration(timeMs)); 13343 } 13344 } 13345 return null; 13346 }; 13347 // Computes the top coordinate, relative to the bounds of the grid, of the given date. 13348 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. 13349 TimeColsSlatsCoords.prototype.computeDateTop = function (when, startOfDayDate) { 13350 if (!startOfDayDate) { 13351 startOfDayDate = startOfDay(when); 13352 } 13353 return this.computeTimeTop(createDuration(when.valueOf() - startOfDayDate.valueOf())); 13354 }; 13355 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). 13356 // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform. 13357 // Eventually allow computation with arbirary slat dates. 13358 TimeColsSlatsCoords.prototype.computeTimeTop = function (duration) { 13359 var _a = this, positions = _a.positions, dateProfile = _a.dateProfile; 13360 var len = positions.els.length; 13361 // floating-point value of # of slots covered 13362 var slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / asRoughMs(this.slotDuration); 13363 var slatIndex; 13364 var slatRemainder; 13365 // compute a floating-point number for how many slats should be progressed through. 13366 // from 0 to number of slats (inclusive) 13367 // constrained because slotMinTime/slotMaxTime might be customized. 13368 slatCoverage = Math.max(0, slatCoverage); 13369 slatCoverage = Math.min(len, slatCoverage); 13370 // an integer index of the furthest whole slat 13371 // from 0 to number slats (*exclusive*, so len-1) 13372 slatIndex = Math.floor(slatCoverage); 13373 slatIndex = Math.min(slatIndex, len - 1); 13374 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition. 13375 // could be 1.0 if slatCoverage is covering *all* the slots 13376 slatRemainder = slatCoverage - slatIndex; 13377 return positions.tops[slatIndex] + 13378 positions.getHeight(slatIndex) * slatRemainder; 13379 }; 13380 return TimeColsSlatsCoords; 13381 }()); 13382 13383 var TimeColsSlatsBody = /** @class */ (function (_super) { 13384 __extends(TimeColsSlatsBody, _super); 13385 function TimeColsSlatsBody() { 13386 return _super !== null && _super.apply(this, arguments) || this; 13387 } 13388 TimeColsSlatsBody.prototype.render = function () { 13389 var _a = this, props = _a.props, context = _a.context; 13390 var options = context.options; 13391 var slatElRefs = props.slatElRefs; 13392 return (createElement("tbody", null, props.slatMetas.map(function (slatMeta, i) { 13393 var hookProps = { 13394 time: slatMeta.time, 13395 date: context.dateEnv.toDate(slatMeta.date), 13396 view: context.viewApi, 13397 }; 13398 var classNames = [ 13399 'fc-timegrid-slot', 13400 'fc-timegrid-slot-lane', 13401 slatMeta.isLabeled ? '' : 'fc-timegrid-slot-minor', 13402 ]; 13403 return (createElement("tr", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) }, 13404 props.axis && (createElement(TimeColsAxisCell, __assign({}, slatMeta))), 13405 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
13405oncat(customClassNames).join(' '), "data-time": slatMeta.isoTimeStr }, innerContent)); }))); 13406 }))); 13407 }; 13408 return TimeColsSlatsBody; 13409 }(BaseComponent)); 13410 13411 /* 13412 for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL. 13413 */ 13414 var TimeColsSlats = /** @class */ (function (_super) { 13415 __extends(TimeColsSlats, _super); 13416 function TimeColsSlats() { 13417 var _this = _super !== null && _super.apply(this, arguments) || this; 13418 _this.rootElRef = createRef(); 13419 _this.slatElRefs = new RefMap(); 13420 return _this; 13421 } 13422 TimeColsSlats.prototype.render = function () { 13423 var _a = this, props = _a.props, context = _a.context; 13424 return (createElement("div", { ref: this.rootElRef, className: "fc-timegrid-slots" }, 13425 createElement("table", { "aria-hidden": true, className: context.theme.getClass('table'), style: { 13426 minWidth: props.tableMinWidth, 13427 width: props.clientWidth, 13428 height: props.minHeight, 13429 } }, 13430 props.tableColGroupNode /* relies on there only being a single <col> for the axis */, 13431 createElement(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas })))); 13432 }; 13433 TimeColsSlats.prototype.componentDidMount = function () { 13434 this.updateSizing(); 13435 }; 13436 TimeColsSlats.prototype.componentDidUpdate = function () { 13437 this.updateSizing(); 13438 }; 13439 TimeColsSlats.prototype.componentWillUnmount = function () { 13440 if (this.props.onCoords) { 13441 this.props.onCoords(null); 13442 } 13443 }; 13444 TimeColsSlats.prototype.updateSizing = function () { 13445 var _a = this, context = _a.context, props = _a.props; 13446 if (props.onCoords && 13447 props.clientWidth !== null // means sizing has stabilized 13448 ) { 13449 var rootEl = this.rootElRef.current; 13450 if (rootEl.offsetHeight) { // not hidden by css 13451 props.onCoords(new TimeColsSlatsCoords(new PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration)); 13452 } 13453 } 13454 }; 13455 return TimeColsSlats; 13456 }(BaseComponent)); 13457 function collectSlatEls(elMap, slatMetas) { 13458 return slatMetas.map(function (slatMeta) { return elMap[slatMeta.key]; }); 13459 } 13460 13461 function splitSegsByCol(segs, colCnt) { 13462 var segsByCol = []; 13463 var i; 13464 for (i = 0; i < colCnt; i += 1) { 13465 segsByCol.push([]); 13466 } 13467 if (segs) { 13468 for (i = 0; i < segs.length; i += 1) { 13469 segsByCol[segs[i].col].push(segs[i]); 13470 } 13471 } 13472 return segsByCol; 13473 } 13474 function splitInteractionByCol(ui, colCnt) { 13475 var byRow = []; 13476 if (!ui) { 13477 for (var i = 0; i < colCnt; i += 1) { 13478 byRow[i] = null; 13479 } 13480 } 13481 else { 13482 for (var i = 0; i < colCnt; i += 1) { 13483 byRow[i] = { 13484 affectedInstances: ui.affectedInstances, 13485 isEvent: ui.isEvent, 13486 segs: [], 13487 }; 13488 } 13489 for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) { 13490 var seg = _a[_i]; 13491 byRow[seg.col].segs.push(seg); 13492 } 13493 } 13494 return byRow; 13495 } 13496 13497 var TimeColMoreLink = /** @class */ (function (_super) { 13498 __extends(TimeColMoreLink, _super); 13499 function TimeColMoreLink() { 13500 var _this = _super !== null && _super.apply(this, arguments) || this; 13501 _this.rootElRef = createRef(); 13502 return _this; 13503 } 13504 TimeColMoreLink.prototype.render = function () { 13505 var _this = this; 13506 var props = this.props; 13507 return (createElement(MoreLinkRoot, { allDayDate: null, moreCnt: props.hiddenSegs.length, allSegs: props.hiddenSegs, hiddenSegs: props.hiddenSegs, al
13507ignmentElRef: 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) { 13508 setRef(rootElRef, el); 13509 setRef(_this.rootElRef, el); 13510 }, 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 }, 13511 createElement("div", { ref: innerElRef, className: "fc-timegrid-more-link-inner fc-sticky" }, innerContent))); })); 13512 }; 13513 return TimeColMoreLink; 13514 }(BaseComponent)); 13515 function renderMoreLinkInner(props) { 13516 return props.shortText; 13517 } 13518 13519 // segInputs assumed sorted 13520 function buildPositioning(segInputs, strictOrder, maxStackCnt) { 13521 var hierarchy = new SegHierarchy(); 13522 if (strictOrder != null) { 13523 hierarchy.strictOrder = strictOrder; 13524 } 13525 if (maxStackCnt != null) { 13526 hierarchy.maxStackCnt = maxStackCnt; 13527 } 13528 var hiddenEntries = hierarchy.addSegs(segInputs); 13529 var hiddenGroups = groupIntersectingEntries(hiddenEntries); 13530 var web = buildWeb(hierarchy); 13531 web = stretchWeb(web, 1); // all levelCoords/thickness will have 0.0-1.0 13532 var segRects = webToRects(web); 13533 return { segRects: segRects, hiddenGroups: hiddenGroups }; 13534 } 13535 function buildWeb(hierarchy) { 13536 var entriesByLevel = hierarchy.entriesByLevel; 13537 var buildNode = cacheable(function (level, lateral) { return level + ':' + lateral; }, function (level, lateral) { 13538 var siblingRange = findNextLevelSegs(hierarchy, level, lateral); 13539 var nextLevelRes = buildNodes(siblingRange, buildNode); 13540 var entry = entriesByLevel[level][lateral]; 13541 return [ 13542 __assign(__assign({}, entry), { nextLevelNodes: nextLevelRes[0] }), 13543 entry.thickness + nextLevelRes[1], // the pressure builds 13544 ]; 13545 }); 13546 return buildNodes(entriesByLevel.length 13547 ? { level: 0, lateralStart: 0, lateralEnd: entriesByLevel[0].length } 13548 : null, buildNode)[0]; 13549 } 13550 function buildNodes(siblingRange, buildNode) { 13551 if (!siblingRange) { 13552 return [[], 0]; 13553 } 13554 var level = siblingRange.level, lateralStart = siblingRange.lateralStart, lateralEnd = siblingRange.lateralEnd; 13555 var lateral = lateralStart; 13556 var pairs = []; 13557 while (lateral < lateralEnd) { 13558 pairs.push(buildNode(level, lateral)); 13559 lateral += 1; 13560 } 13561 pairs.sort(cmpDescPressures); 13562 return [ 13563 pairs.map(extractNode), 13564 pairs[0][1], // first item's pressure 13565 ]; 13566 } 13567 function cmpDescPressures(a, b) { 13568 return b[1] - a[1]; 13569 } 13570 function extractNode(a) { 13571 return a[0]; 13572 } 13573 function findNextLevelSegs(hierarchy, subjectLevel, subjectLateral) { 13574 var levelCoords = hierarchy.levelCoords, entriesByLevel = hierarchy.entriesByLevel; 13575 var subjectEntry = entriesByLevel[subjectLevel][subjectLateral]; 13576 var afterSubject = levelCoords[subjectLevel] + subjectEntry.thickness; 13577 var levelCnt = levelCoords.length; 13578 var level = subjectLevel; 13579 // skip past levels that are too high up 13580 for (; level < levelCnt && levelCoords[level] < afterSubject; level += 1) 13581 ; // do nothing 13582 for (; level < levelCnt; level += 1) { 13583 var entries = entriesByLevel[level]; 13584 var entry = void 0; 13585 var searchIndex = binarySearch(entries, subjectEntry.span.start, getEntrySpanEnd); 13586 var lateralStart = searchIndex[0] + searchIndex[1]; // if exact match (which doesn't collide), go to next one 13587 var lateralEnd = lateralStart; 13588 while ( // loop through entries that horizontally intersect 13589 (entry = entries[lateralEnd]) && // but not past the whole seg list 13590 entry.span.start < subjectEntry.span.end) { 13591 lateralEnd += 1; 13592 } 13593 if (lateralStart < lateralEnd) { 13594 return { level: level, lateralStart: lateralStart, lateralEnd: lateralEnd }; 13595 } 13596 } 13597 return null; 13598 } 13599 function stretchWeb(topLevelNodes, totalThickness) { 13600 var stretchNode = cacheable(function (node, startCoord, prevThickness) { return buildEntryKey(node); }, function (node, startCoord, prevThickness) { 13601 var nextLevelNodes = node.nextLevelNodes, thickness = node.thickness; 13602 var allThickness = thickness + prevThickness; 13603 var thicknessFraction = thickness / allThickness; 13604 var endCoord; 13605 var newChildren = []; 13606 if (!nextLevelNodes.length) { 13607 endCoord = totalThickness; 13608 } 13609 else { 13610 for (var _i = 0, nextLevelNodes_1 = nextLevelNodes; _i < nextLevelNodes_1.length; _i++) { 13611 var childNode = nextLevelNodes_1[_i]; 13612 if (endCoord === undefined) { 13613 var res = stretchNode(childNode, startCoord, allThickness); 13614 endCoord = res[0]; 13615 newChildren.push(res[1]); 13616 } 13617 else { 13618 var res = stretchNode(childNode, endCoord, 0); 13619 newChildren.push(res[1]); 13620 } 13621 } 13622 } 13623 var newThickness = (endCoord - startCoord) * thicknessFraction; 13624 return [endCoord - newThickness, __assign(__assign({}, node), { thickness: newThickness, nextLevelNodes: newChildren })]; 13625 }); 13626 return topLevelNodes.map(function (node) { return stretchNode(node,
136260, 0)[1]; }); 13627 } 13628 // not sorted in any particular order 13629 function webToRects(topLevelNodes) { 13630 var rects = []; 13631 var processNode = cacheable(function (node, levelCoord, stackDepth) { return buildEntryKey(node); }, function (node, levelCoord, stackDepth) { 13632 var rect = __assign(__assign({}, node), { levelCoord: levelCoord, 13633 stackDepth: stackDepth, stackForward: 0 }); 13634 rects.push(rect); 13635 return (rect.stackForward = processNodes(node.nextLevelNodes, levelCoord + node.thickness, stackDepth + 1) + 1); 13636 }); 13637 function processNodes(nodes, levelCoord, stackDepth) { 13638 var stackForward = 0; 13639 for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) { 13640 var node = nodes_1[_i]; 13641 stackForward = Math.max(processNode(node, levelCoord, stackDepth), stackForward); 13642 } 13643 return stackForward; 13644 } 13645 processNodes(topLevelNodes, 0, 0); 13646 return rects; // TODO: sort rects by levelCoord to be consistent with toRects? 13647 } 13648 // TODO: move to general util 13649 function cacheable(keyFunc, workFunc) { 13650 var cache = {}; 13651 return function () { 13652 var args = []; 13653 for (var _i = 0; _i < arguments.length; _i++) { 13654 args[_i] = arguments[_i]; 13655 } 13656 var key = keyFunc.apply(void 0, args); 13657 return (key in cache) 13658 ? cache[key] 13659 : (cache[key] = workFunc.apply(void 0, args)); 13660 }; 13661 } 13662 13663 function computeSegVCoords(segs, colDate, slatCoords, eventMinHeight) { 13664 if (slatCoords === void 0) { slatCoords = null; } 13665 if (eventMinHeight === void 0) { eventMinHeight = 0; } 13666 var vcoords = []; 13667 if (slatCoords) { 13668 for (var i = 0; i < segs.length; i += 1) { 13669 var seg = segs[i]; 13670 var spanStart = slatCoords.computeDateTop(seg.start, colDate); 13671 var spanEnd = Math.max(spanStart + (eventMinHeight || 0), // :( 13672 slatCoords.computeDateTop(seg.end, colDate)); 13673 vcoords.push({ 13674 start: Math.round(spanStart), 13675 end: Math.round(spanEnd), // 13676 }); 13677 } 13678 } 13679 return vcoords; 13680 } 13681 function computeFgSegPlacements(segs, segVCoords, // might not have for every seg 13682 eventOrderStrict, eventMaxStack) { 13683 var segInputs = []; 13684 var dumbSegs = []; // segs without coords 13685 for (var i = 0; i < segs.length; i += 1) { 13686 var vcoords = segVCoords[i]; 13687 if (vcoords) { 13688 segInputs.push({ 13689 index: i, 13690 thickness: 1, 13691 span: vcoords, 13692 }); 13693 } 13694 else { 13695 dumbSegs.push(segs[i]); 13696 } 13697 } 13698 var _a = buildPositioning(segInputs, eventOrderStrict, eventMaxStack), segRects = _a.segRects, hiddenGroups = _a.hiddenGroups; 13699 var segPlacements = []; 13700 for (var _i = 0, segRects_1 = segRects; _i < segRects_1.length; _i++) { 13701 var segRect = segRects_1[_i]; 13702 segPlacements.push({ 13703 seg: segs[segRect.index], 13704 rect: segRect, 13705 }); 13706 } 13707 for (var _b = 0, dumbSegs_1 = dumbSegs; _b < dumbSegs_1.length; _b++) { 13708 var dumbSeg = dumbSegs_1[_b]; 13709 segPlacements.push({ seg: dumbSeg, rect: null }); 13710 } 13711 return { segPlacements: segPlacements, hiddenGroups: hiddenGroups }; 13712 } 13713 13714 var DEFAULT_TIME_FORMAT$1 = createFormatter({ 13715 hour: 'numeric', 13716 minute: '2-digit', 13717 meridiem: false, 13718 }); 13719 var TimeColEvent = /** @class */ (function (_super) { 13720 __extends(TimeColEvent, _super); 13721 function TimeColEvent() { 13722 return _super !== null && _super.apply(this, arguments) || this; 13723 } 13724 TimeColEvent.prototype.render = function () { 13725 var classNames = [ 13726 'fc-timegrid-event', 13727 'fc-v-event', 13728 ]; 13729 if (this.props.isShort) { 13730 classNames.push('fc-timegrid-event-short'); 13731 } 13732 return (createElement(StandardEvent, __assign({}, this.props, { defaultTimeFormat: DEFAULT_TIME_FORMAT$1, extraClassNames: classNames }))); 13733 }; 13734 return TimeColEvent; 13735 }(BaseComponent)); 13736 13737 var TimeColMisc = /** @class */ (function (_super) { 13738 __extends(TimeColMisc, _super); 13739 function TimeColMisc() { 13740 return _super !== null && _super.apply(this, arguments) || this; 13741 } 13742 TimeColMisc.prototype.render = function () { 13743 var props = this.props; 13744 return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (innerElRef, innerContent) { return (innerContent && 13745 createElement("div", { className: "fc-timegrid-col-misc", ref: innerElRef }, innerContent)); })); 13746 }; 13747 return TimeColMisc; 13748 }(BaseComponent)); 13749 13750 var TimeCol = /** @class */ (function (_super) { 13751 __extends(TimeCol, _super); 13752 function TimeCol() { 13753 var _this = _super !== null && _super.apply(this, arguments) || this; 13754 _this.sortEventSegs = memoize(sortEventSegs); 13755 return _this; 13756 } 13757 // TODO: memoize event-placement? 13758 TimeCol.prototype.render = function () { 13759 var _this = this; 13760 var _a = this, props = _a.props, context = _a.context; 13761 var isSelectMirror = context.options.selectMirror; 13762 var mirrorSegs = (props.eventDrag && props.eventDrag.segs) || 13763 (props.eventResize && props.eventResize.segs) || 13764 (isSelectMirror && props.dateSelectionSegs) || 13765 []; 13766 var interactionAffectedInstances = // TODO: messy way to compute this 13767 (props.eventDrag && props.eventDrag.affectedInstances) || 13768 (props.eventResize && props.eventResize.affectedInstances) || 13769 {}; 13770 var sortedFgSegs = this.sortEventSegs(props.fgEventSegs, context.options.eventOrder); 13771 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), 13772 createElement("div", { className: "fc-timegrid-col-frame" }, 13773 createElement("div", { className: "fc-timegrid-col-bg" }, 13774 _this.renderFillSegs(props.businessHourSegs, 'non-business'), 13775 _this.renderFillSegs(props.bgEventSegs, 'bg-event'), 13776 _this.renderFillSegs(props.dateSelectionSegs, 'highlight')), 13777 createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(sortedFgSegs, interactionAffectedInstances, false, false, false)), 13778 createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror))), 13779 createElement("div", { className: "fc-timegrid-now-indicator-container" }, _this.renderNowIndicator(props.nowIndicatorSegs)), 13780 createElement(TimeColMisc, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps })))); })); 13781 }; 13782 TimeCol.prototype.renderFgSegs = function (sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting) { 13783 var props = this.props; 13784 if (props.forPrint) { 13785 return renderPlainFgSegs(sortedFgSegs, props); 13786 } 13787 return this.renderPositionedFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting); 13788 }; 13789 TimeCol.prototype.renderPositionedFgSegs = function (segs, // if not mirror, needs to be sorted 13790 segIsInvisible, isDragging, isResizing, isDateSelecting) { 13791 var _this = this; 13792 var _a = this.context.options, eventMaxStack = _a.eventMaxStack, eventShortHeight = _a.eventShortHeight, eventOrderStrict = _a.eventOrderStrict, eventMinHeight = _a.eventMinHeight; 13793 var _b = this.props, date = _b.date, slatCoords = _b.slatCoords, eventSelection = _b.eventSelection, todayRange = _b.todayRange, nowDate = _b.nowDate; 13794 var isMirror = isDragging || isResizing || isDateSelecting; 13795 var segVCoords = computeSegVCoords(segs, date, slatCoords, eventMinHeight); 13796 var _c = computeFgSegPlacements(segs, segVCoords, eventOrderStrict, eventMaxStack), segPlacements = _c.segPlacements, hiddenGroups = _c.hiddenGroups; 13797 return (createElement(Fragment, null, 13798 this.renderHiddenGroups(hiddenGroups, segs), 13799 segPlacements.map(function (segPlacement) { 13800 var seg = segPlacement.seg, rect = segPlacement.rect; 13801 var instanceId = seg.eventRange.instance.instanceId; 13802 var isVisible = isMirror || Boolean(!segIsInvisible[instanceId] && rect); 13803 var vStyle = computeSegVStyle(rect && rect.span); 13804 var hStyle = (!isMirror && rect) ? _this.computeSegHStyle(rect) : { left: 0, right: 0 }; 13805 var isInset = Boolean(rect) && rect.stackForward > 0;
13806 var isShort = Boolean(rect) && (rect.span.end - rect.span.start) < eventShortHeight; // look at other places for this problem 13807 return (createElement("div", { className: 'fc-timegrid-event-harness' + 13808 (isInset ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: __assign(__assign({ visibility: isVisible ? '' : 'hidden' }, vStyle), hStyle) }, 13809 createElement(TimeColEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, isShort: isShort }, getSegMeta(seg, todayRange, nowDate))))); 13810 }))); 13811 }; 13812 // will already have eventMinHeight applied because segInputs already had it 13813 TimeCol.prototype.renderHiddenGroups = function (hiddenGroups, segs) { 13814 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; 13815 return (createElement(Fragment, null, hiddenGroups.map(function (hiddenGroup) { 13816 var positionCss = computeSegVStyle(hiddenGroup.span); 13817 var hiddenSegs = compileSegsFromEntries(hiddenGroup.entries, segs); 13818 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 })); 13819 }))); 13820 }; 13821 TimeCol.prototype.renderFillSegs = function (segs, fillType) { 13822 var _a = this, props = _a.props, context = _a.context; 13823 var segVCoords = computeSegVCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight); // don't assume all populated 13824 var children = segVCoords.map(function (vcoords, i) { 13825 var seg = segs[i]; 13826 return (createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-timegrid-bg-harness", style: computeSegVStyle(vcoords) }, fillType === 'bg-event' ? 13827 createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, props.todayRange, props.nowDate))) : 13828 renderFill(fillType))); 13829 }); 13830 return createElement(Fragment, null, children); 13831 }; 13832 TimeCol.prototype.renderNowIndicator = function (segs) { 13833 var _a = this.props, slatCoords = _a.slatCoords, date = _a.date; 13834 if (!slatCoords) { 13835 return null; 13836 } 13837 return segs.map(function (seg, i) { return (createElement(NowIndicatorRoot, { isAxis: false, date: date, 13838 // key doesn't matter. will only ever be one 13839 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)); })); }); 13840 }; 13841 TimeCol.prototype.computeSegHStyle = function (segHCoords) { 13842 var _a = this.context, isRtl = _a.isRtl, options = _a.options; 13843 var shouldOverlap = options.slotEventOverlap; 13844 var nearCoord = segHCoords.levelCoord; // the left side if LTR. the right side if RTL. floating-point 13845 var farCoord = segHCoords.levelCoord + segHCoords.thickness; // the right side if LTR. the left side if RTL. floating-point 13846 var left; // amount of space from left edge, a fraction of the total width 13847 var right; // amount of space from right edge, a fraction of the total width 13848 if (shouldOverlap) { 13849 // double the width, but don't go beyond the maximum forward coordinate (1.0) 13850 farCoord = Math.min(1, nearCoord + (farCoord - nearCoord) * 2); 13851 } 13852 if (isRtl) { 13853 left = 1 - farCoord; 13854 right = nearCoord; 13855 } 13856 else { 13857 left = nearCoord; 13858 right = 1 - farCoord; 13859 } 13860 var props = { 13861 zIndex: segHCoords.stackDepth + 1, 13862 left: left * 100 + '%', 13863 right: right * 100 + '%', 13864 }; 13865 if (shouldOverlap && !segHCoords.stackForward) { 13866 // add padding to the edge so that forward stacked events don't cover the resizer's icon 13867 props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width 13868 } 13869 return props; 13870 }; 13871 return TimeCol; 13872 }(BaseComponent)); 13873 function renderPlainFgSegs(sortedFgSegs, _a) { 13874 var todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize; 13875 var hiddenInstances = (eventDrag ? eventDrag.affectedInstances : null) || 13876 (eventResize ? eventResize.affectedInstances : null) || 13877 {}; 13878 return (createElement(Fragment, null, sortedFgSegs.map(function (seg) { 13879 var instanceId = seg.eventRange.instance.instanceId; 13880 return (createElement("div", { key: instanceId, style: { visibility: hiddenInstances[instanceId] ? 'hidden' : '' } }, 13881 createElement(TimeColEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === eventSelection, isShort: false }, getSegMeta(seg, todayRange, nowDate))))); 13882 }))); 13883 } 13884 function computeSegVStyle(segVCoords) { 13885 if (!segVCoords) { 13886 return { top: '', bottom: '' }; 13887 } 13888 return { 13889 top: segVCoords.start, 13890 bottom: -segVCoords.end, 13891 }; 13892 } 13893 function compileSegsFromEntries(segEntries, allSegs) { 13894 return segEntries.map(function (segEntry) { return allSegs[segEntry.index]; }); 13895 } 13896 13897 var TimeColsContent = /** @class */ (function (_super) { 13898 __extends(TimeColsContent, _super); 13899 function TimeColsContent() { 13900 var _this = _super !== null && _super.apply(this, arguments) || this; 13901 _this.splitFgEventSegs = memoize(splitSegsByCol); 13902 _this.splitBgEventSegs = memoize(splitSegsByCol); 13903 _this.splitBusinessHourSegs = memoize(splitSegsByCol); 13904 _this.splitNowIndicatorSegs = memoize(splitSegsByCol); 13905 _this.splitDateSelectionSegs = memoize(splitSegsByCol); 13906 _this.splitEventDrag = memoize(splitInteractionByCol); 13907 _this.splitEventResize = memoize(splitInteractionByCol); 13908 _this.rootElRef = createRef(); 13909 _this.cellElRefs = new RefMap(); 13910 return _this; 13911 } 13912 TimeColsContent.prototype.render = function () { 13913 var _this = this; 13914 var _a = this, props = _a.props, context = _a.context; 13915 var nowIndicatorTop = context.options.nowIndicator && 13916 props.slatCoords && 13917 props.slatCoords.safeComputeTop(props.nowDate); // might return void 13918 var colCnt = props.cells.length; 13919 var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt); 13920 var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt); 13921 var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt); 13922 var nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt); 13923 var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt); 13924 var eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt); 13925 var eventResizeByRow = this.splitEventResize(props.eventResize, colCnt); 13926 return (createElement("div", { className: "fc-timegrid-cols", ref: this.rootElRef }, 13927 createElement("table", { role: "presentation", style: { 13928 minWidth: props.tableMinWidth, 13929 width: props.clientWidth, 13930 } }, 13931 props.tableColGroupNode, 13932 createElement("tbody", { role: "presentation" }, 13933 createElement("tr", { role: "row" }, 13934 props.axis && (createElement("td", { "aria-hidden": true, className: "fc-timegrid-col fc-timegrid-axis" }, 13935 createElement("div", { className: "fc-timegrid-col-frame" }, 13936 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)); })))))), 13937 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 })); })))))); 13938 }; 13939 TimeColsContent.prototype.componentDidMount = function () { 13940 this.updateCoords(); 13941 }; 13942 TimeColsContent.prototype.componentDidUpdate = function () { 13943 this.updateCoords(); 13944 }; 13945 TimeColsContent.prototype.updateCoords = function () { 13946 var props = this.props; 13947 if (props.onColCoords && 13948 props.clientWidth !== null // means sizing has stabilized 13949 ) { 13950 props.onColCoords(new PositionCache(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal 13951 false)); 13952 } 13953 }; 13954 return TimeColsContent; 13955 }(BaseComponent)); 13956 function collectCellEls(elMap, cells) { 13957 return cells.map(function (cell) { return elMap[cell.key]; }); 13958 } 13959 13960 /* A component that renders one or more columns of vertical time slots 13961 ----------------------------------------------------------------------------------------------------------------------*/ 13962 var TimeCols = /** @class */ (function (_super) { 13963 __extends(TimeCols, _super); 13964 function TimeCols() { 13965 var _this = _super !== null && _super.apply(this, arguments) || this; 13966 _this.processSlotOptions = memoize(processSlotOptions); 13967 _this.state = { 13968 slatCoords: null, 13969 }; 13970 _this.handleRootEl = function (el) { 13971 if (el) { 13972 _this.context.registerInteractiveComponent(_this, { 13973 el: el, 13974 isHitComboAllowed: _this.props.isHitComboAllowed, 13975 }); 13976 } 13977 else { 13978 _this.context.unregisterInteractiveComponent(_this); 13979 } 13980 }; 13981 _this.handleScrollRequest = function (request) { 13982 var onScrollTopRequest = _this.props.onScrollTopRequest; 13983 var slatCoords = _this.state.slatCoords; 13984 if (onScrollTopRequest && slatCoords) { 13985 if (request.time) { 13986 var top_1 = slatCoords.computeTimeTop(request.time); 13987 top_1 = Math.ceil(top_1); // zoom can give weird floating-point values. rather scroll a little bit further 13988 if (top_1) { 13989 top_1 += 1; // to overcome top border that slots beyond the first have. looks better 13990 } 13991 onScrollTopRequest(top_1); 13992 } 13993 return true; 13994 } 13995 return false; 13996 }; 13997 _this.handleColCoords = function (colCoords) { 13998 _this.colCoords = colCoords; 13999 }; 14000 _this.handleSlatCoords = function (slatCoords) {
14001 _this.setState({ slatCoords: slatCoords }); 14002 if (_this.props.onSlatCoords) { 14003 _this.props.onSlatCoords(slatCoords); 14004 } 14005 }; 14006 return _this; 14007 } 14008 TimeCols.prototype.render = function () { 14009 var _a = this, props = _a.props, state = _a.state; 14010 return (createElement("div", { className: "fc-timegrid-body", ref: this.handleRootEl, style: { 14011 // these props are important to give this wrapper correct dimensions for interactions 14012 // TODO: if we set it here, can we avoid giving to inner tables? 14013 width: props.clientWidth, 14014 minWidth: props.tableMinWidth, 14015 } }, 14016 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 }), 14017 createElement(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bg
14017EventSegs, 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 }))); 14018 }; 14019 TimeCols.prototype.componentDidMount = function () { 14020 this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest); 14021 }; 14022 TimeCols.prototype.componentDidUpdate = function (prevProps) { 14023 this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile); 14024 }; 14025 TimeCols.prototype.componentWillUnmount = function () { 14026 this.scrollResponder.detach(); 14027 }; 14028 TimeCols.prototype.queryHit = function (positionLeft, positionTop) { 14029 var _a = this.context, dateEnv = _a.dateEnv, options = _a.options; 14030 var colCoords = this.colCoords; 14031 var dateProfile = this.props.dateProfile; 14032 var slatCoords = this.state.slatCoords; 14033 var _b = this.processSlotOptions(this.props.slotDuration, options.snapDuration), snapDuration = _b.snapDuration, snapsPerSlot = _b.snapsPerSlot; 14034 var colIndex = colCoords.leftToIndex(positionLeft); 14035 var slatIndex = slatCoords.positions.topToIndex(positionTop); 14036 if (colIndex != null && slatIndex != null) { 14037 var cell = this.props.cells[colIndex]; 14038 var slatTop = slatCoords.positions.tops[slatIndex]; 14039 var slatHeight = slatCoords.positions.getHeight(slatIndex); 14040 var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1 14041 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat 14042 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex; 14043 var dayDate = this.props.cells[colIndex].date; 14044 var time = addDurations(dateProfile.slotMinTime, multiplyDuration(snapDuration, snapIndex)); 14045 var start = dateEnv.add(dayDate, time); 14046 var end = dateEnv.add(start, snapDuration); 14047 return { 14048 dateProfile: dateProfile, 14049 dateSpan: __assign({ range: { start: start, end: end }, allDay: false }, cell.extraDateSpan), 14050 dayEl: colCoords.els[colIndex], 14051 rect: { 14052 left: colCoords.lefts[colIndex], 14053 right: colCoords.rights[colIndex], 14054 top: slatTop, 14055 bottom: slatTop + slatHeight, 14056 }, 14057 layer: 0, 14058 }; 14059 } 14060 return null; 14061 }; 14062 return TimeCols; 14063 }(DateComponent)); 14064 function processSlotOptions(slotDuration, snapDurationOverride) { 14065 var snapDuration = snapDurationOverride || slotDuration; 14066 var snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration); 14067 if (snapsPerSlot === null) { 14068 snapDuration = slotDuration; 14069 snapsPerSlot = 1; 14070 // TODO: say warning? 14071 } 14072 return { snapDuration: snapDuration, snapsPerSlot: snapsPerSlot }; 14073 } 14074 14075 var DayTimeColsSlicer = /** @class */ (function (_super) { 14076 __extends(DayTimeColsSlicer, _super); 14077 function DayTimeColsSlicer() { 14078 return _super !== null && _super.apply(this, arguments) || this; 14079 } 14080 DayTimeColsSlicer.prototype.sliceRange = function (range, dayRanges) { 14081 var segs = []; 14082 for (var col = 0; col < dayRanges.length; col += 1) { 14083 var segRange = intersectRanges(range, dayRanges[col]); 14084 if (segRange) { 14085 segs.push({ 14086 start: segRange.start, 14087 end: segRange.end, 14088 isStart: segRange.start.valueOf() === range.start.valueOf(), 14089 isEnd: segRange.end.valueOf() === range.end.valueOf(), 14090 col: col, 14091 }); 14092 } 14093 } 14094 return segs; 14095 }; 14096 return DayTimeColsSlicer; 14097 }(Slicer));
14098 14099 var DayTimeCols = /** @class */ (function (_super) { 14100 __extends(DayTimeCols, _super); 14101 function DayTimeCols() { 14102 var _this = _super !== null && _super.apply(this, arguments) || this; 14103 _this.buildDayRanges = memoize(buildDayRanges); 14104 _this.slicer = new DayTimeColsSlicer(); 14105 _this.timeColsRef = createRef(); 14106 return _this; 14107 } 14108 DayTimeCols.prototype.render = function () { 14109 var _this = this; 14110 var _a = this, props = _a.props, context = _a.context; 14111 var dateProfile = props.dateProfile, dayTableModel = props.dayTableModel; 14112 var isNowIndicator = context.options.nowIndicator; 14113 var dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv); 14114 // give it the first row of cells 14115 // TODO: would move this further down hierarchy, but sliceNowDate needs it 14116 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 }))); })); 14117 }; 14118 return DayTimeCols; 14119 }(DateComponent)); 14120 function buildDayRanges(dayTableModel, dateProfile, dateEnv) { 14121 var ranges = []; 14122 for (var _i = 0, _a = dayTableModel.headerDates; _i < _a.length; _i++) { 14123 var date = _a[_i]; 14124 ranges.push({ 14125 start: dateEnv.add(date, dateProfile.slotMinTime), 14126 end: dateEnv.add(date, dateProfile.slotMaxTime), 14127 }); 14128 } 14129 return ranges; 14130 } 14131 14132 // potential nice values for the slot-duration and interval-duration 14133 // from largest to smallest 14134 var STOCK_SUB_DURATIONS = [ 14135 { hours: 1 }, 14136 { minutes: 30 }, 14137 { minutes: 15 }, 14138 { seconds: 30 }, 14139 { seconds: 15 }, 14140 ]; 14141 function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) { 14142 var dayStart = new Date(0); 14143 var slatTime = slotMinTime; 14144 var slatIterator = createDuration(0); 14145 var labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration); 14146 var metas = []; 14147 while (asRoughMs(slatTime) < asRoughMs(slotMaxTime)) { 14148 var date = dateEnv.add(dayStart, slatTime); 14149 var isLabeled = wholeDivideDurations(slatIterator, labelInterval) !== null; 14150 metas.push({ 14151 date: date, 14152 time: slatTime, 14153 key: date.toISOString(), 14154 isoTimeStr: formatIsoTimeString(date), 14155 isLabeled: isLabeled, 14156 }); 14157 slatTime = addDurations(slatTime, slotDuration); 14158 slatIterator = addDurations(slatIterator, slotDuration); 14159 } 14160 return metas; 14161 } 14162 // Computes an automatic value for slotLabelInterval 14163 function computeLabelInterval(slotDuration) { 14164 var i; 14165 var labelInterval; 14166 var slotsPerLabel; 14167 // find the smallest stock label interval that results in more than one slots-per-label 14168 for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i -= 1) { 14169 labelInterval = createDuration(STOCK_SUB_DURATIONS[i]); 14170 slotsPerLabel = wholeDivideDurations(labelInterval, slotDuration);
14171 if (slotsPerLabel !== null && slotsPerLabel > 1) { 14172 return labelInterval; 14173 } 14174 } 14175 return slotDuration; // fall back 14176 } 14177 14178 var DayTimeColsView = /** @class */ (function (_super) { 14179 __extends(DayTimeColsView, _super); 14180 function DayTimeColsView() { 14181 var _this = _super !== null && _super.apply(this, arguments) || this; 14182 _this.buildTimeColsModel = memoize(buildTimeColsModel); 14183 _this.buildSlatMetas = memoize(buildSlatMetas); 14184 return _this; 14185 } 14186 DayTimeColsView.prototype.render = function () { 14187 var _this = this; 14188 var _a = this.context, options = _a.options, dateEnv = _a.dateEnv, dateProfileGenerator = _a.dateProfileGenerator; 14189 var props = this.props; 14190 var dateProfile = props.dateProfile; 14191 var dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator); 14192 var splitProps = this.allDaySplitter.splitProps(props); 14193 var slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv); 14194 var dayMinWidth = options.dayMinWidth; 14195 var hasAttachedAxis = !dayMinWidth; 14196 var hasDetachedAxis = dayMinWidth; 14197 var headerContent = options.dayHeaders && (createElement(DayHeader, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null })); 14198 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()))); }); 14199 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 }))); }; 14200 return hasDetachedAxis 14201 ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords) 14202 : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent); 14203 }; 14204 return DayTimeColsView; 14205 }(TimeColsView));
14206 function buildTimeColsModel(dateProfile, dateProfileGenerator) { 14207 var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator); 14208 return new DayTableModel(daySeries, false); 14209 } 14210 14211 var OPTION_REFINERS$2 = { 14212 allDaySlot: Boolean, 14213 }; 14214 14215 var timeGridPlugin = createPlugin({ 14216 initialView: 'timeGridWeek', 14217 optionRefiners: OPTION_REFINERS$2, 14218 views: { 14219 timeGrid: { 14220 component: DayTimeColsView, 14221 usesMinMaxTime: true, 14222 allDaySlot: true, 14223 slotDuration: '00:30:00', 14224 slotEventOverlap: true, // a bad name. confused with overlap/constraint system 14225 }, 14226 timeGridDay: { 14227 type: 'timeGrid', 14228 duration: { days: 1 }, 14229 }, 14230 timeGridWeek: { 14231 type: 'timeGrid', 14232 duration: { weeks: 1 }, 14233 }, 14234 }, 14235 }); 14236 14237 var ListViewHeaderRow = /** @class */ (function (_super) { 14238 __extends(ListViewHeaderRow, _super); 14239 function ListViewHeaderRow() { 14240 var _this = _super !== null && _super.apply(this, arguments) || this; 14241 _this.state = { 14242 textId: getUniqueDomId(), 14243 }; 14244 return _this; 14245 } 14246 ListViewHeaderRow.prototype.render = function () { 14247 var _a = this.context, theme = _a.theme, dateEnv = _a.dateEnv, options = _a.options, viewApi = _a.viewApi; 14248 var _b = this.props, cellId = _b.cellId, dayDate = _b.dayDate, todayRange = _b.todayRange; 14249 var textId = this.state.textId; 14250 var dayMeta = getDateMeta(dayDate, todayRange); 14251 // will ever be falsy? 14252 var text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : ''; 14253 // will ever be falsy? also, BAD NAME "alt" 14254 var sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : ''; 14255 var hookProps = __assign({ date: dateEnv.toDate(dayDate), view: viewApi, textId: textId, 14256 text: text, 14257 sideText: sideText, navLinkAttrs: buildNavLinkAttrs(this.context, dayDate), sideNavLinkAttrs: buildNavLinkAttrs(this.context, dayDate, 'day', false) }, dayMeta); 14258 var classNames = ['fc-list-day'].concat(getDayClassNames(dayMeta, theme)); 14259 // TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too) 14260 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) }, 14261 createElement("th", { scope: "colgroup", colSpan: 3, id: cellId, "aria-labelledby": textId }, 14262 createElement("div", { className: 'fc-list-day-cushion ' + theme.getClass('tableCellShaded'), ref: innerElRef }, innerContent)))); })); 14263 }; 14264 return ListViewHeaderRow; 14265 }(BaseComponent)); 14266 function renderInnerContent(props) { 14267 return (createElement(Fragment, null, 14268 props.text && (createElement("a", __assign({ id: props.textId, className: "fc-list-day-text" }, props.navLinkAttrs), props.text)), 14269 props.sideText && ( /* not keyboard tabbable */createElement("a", __assign({ "aria-hidden": true, className: "fc-list-day-side-text" }, props.sideNavLinkAttrs), props.sideText)))); 14270 } 14271 14272 var DEFAULT_TIME_FORMAT = createFormatter({ 14273 hour: 'numeric', 14274 minute: '2-digit', 14275 meridiem: 'short', 14276 }); 14277 var ListViewEventRow = /** @class */ (function (_super) { 14278 __extends(ListViewEventRow, _super); 14279 function ListViewEventRow() { 14280 return _super !== null && _super.apply(this, arguments) || this; 14281 } 14282 ListViewEventRow.prototype.render = function () { 14283 var _a = this, props = _a.props, context = _a.context; 14284 var seg = props.seg, timeHeaderId = props.timeHeaderId, eventHeaderId = props.eventHeaderId, dateHeaderId = props.dateHeaderId;
14285 var timeFormat = context.options.eventTimeFormat || DEFAULT_TIME_FORMAT; 14286 return (createElement(EventRoot, { seg: seg, timeText: "" // BAD. because of all-day content 14287 , 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 }, 14288 buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId), 14289 createElement("td", { "aria-hidden": true, className: "fc-list-event-graphic" }, 14290 createElement("span", { className: "fc-list-event-dot", style: { borderColor: hookProps.borderColor || hookProps.backgroundColor } })), 14291 createElement("td", { ref: innerElRef, headers: eventHeaderId + " " + dateHeaderId, className: "fc-list-event-title" }, innerContent))); })); 14292 }; 14293 return ListViewEventRow; 14294 }(BaseComponent)); 14295 function renderEventInnerContent(seg, context) { 14296 var interactiveAttrs = getSegAnchorAttrs(seg, context); 14297 return (createElement("a", __assign({}, interactiveAttrs), seg.eventRange.def.title)); 14298 } 14299 function buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId) { 14300 var options = context.options; 14301 if (options.displayEventTime !== false) { 14302 var eventDef = seg.eventRange.def; 14303 var eventInstance = seg.eventRange.instance; 14304 var doAllDay = false; 14305 var timeText = void 0; 14306 if (eventDef.allDay) { 14307 doAllDay = true; 14308 } 14309 else if (isMultiDayRange(seg.eventRange.range)) { // TODO: use (!isStart || !isEnd) instead? 14310 if (seg.isStart) { 14311 timeText = buildSegTimeText(seg, timeFormat, context, null, null, eventInstance.range.start, seg.end); 14312 } 14313 else if (seg.isEnd) { 14314 timeText = buildSegTimeText(seg, timeFormat, context, null, null, seg.start, eventInstance.range.end); 14315 } 14316 else { 14317 doAllDay = true; 14318 } 14319 } 14320 else { 14321 timeText = buildSegTimeText(seg, timeFormat, context); 14322 } 14323 if (doAllDay) { 14324 var hookProps = { 14325 text: context.options.allDayText, 14326 view: context.viewApi, 14327 }; 14328 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)); })); 14329 } 14330 return (createElement("td", { className: "fc-list-event-time" }, timeText)); 14331 } 14332 return null; 14333 } 14334 function renderAllDayInner(hookProps) { 14335 return hookProps.text; 14336 } 14337 14338 /* 14339 Responsible for the scroller, and forwarding event-related actions into the "grid". 14340 */ 14341 var ListView = /** @class */ (function (_super) { 14342 __extends(ListView, _super); 14343 function ListView() { 14344 var _this = _super !== null && _super.apply(this, arguments) || this; 14345 _this.computeDateVars = memoize(computeDateVars); 14346 _this.eventStoreToSegs = memoize(_this._eventStoreToSegs); 14347 _this.state = { 14348 timeHeaderId: getUniqueDomId(), 14349 eventHeaderId: getUniqueDomId(), 14350 dateHeaderIdRoot: getUniqueDomId(), 14351 }; 14352 _this.setRootEl = function (rootEl) { 14353 if (rootEl) { 14354 _this.context.registerInteractiveComponent(_this, { 14355 el: rootEl, 14356 }); 14357 } 14358 else { 14359 _this.context.unregisterInteractiveComponent(_this); 14360 } 14361 }; 14362 return _this; 14363 } 14364 ListView.prototype.render = function () { 14365 var _this = this; 14366 var _a = this, props = _a.props, context = _a.context; 14367 var extraClassNames = [ 14368 'fc-list', 14369 context.theme.getClass('table'), 14370 context.options.stickyHeaderDates !== false ? 'fc-list-sticky' : '', 14371 ]; 14372 var _b = this.computeDateVars(props.dateProfile), dayDates = _b.dayDates, dayRanges = _b.dayRanges; 14373 var eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges); 14374 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.setRootEl }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: extraClassNames.c
14374oncat(classNames).join(' ') }, 14375 createElement(Scroller, { liquid: !props.isHeightAuto, overflowX: props.isHeightAuto ? 'visible' : 'hidden', overflowY: props.isHeightAuto ? 'visible' : 'auto' }, eventSegs.length > 0 ? 14376 _this.renderSegList(eventSegs, dayDates) : 14377 _this.renderEmptyMessage()))); })); 14378 }; 14379 ListView.prototype.renderEmptyMessage = function () { 14380 var _a = this.context, options = _a.options, viewApi = _a.viewApi; 14381 var hookProps = { 14382 text: options.noEventsText, 14383 view: viewApi, 14384 }; 14385 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 }, 14386 createElement("div", { className: "fc-list-empty-cushion", ref: innerElRef }, innerContent))); })); 14387 }; 14388 ListView.prototype.renderSegList = function (allSegs, dayDates) { 14389 var _a = this.context, theme = _a.theme, options = _a.options; 14390 var _b = this.state, timeHeaderId = _b.timeHeaderId, eventHeaderId = _b.eventHeaderId, dateHeaderIdRoot = _b.dateHeaderIdRoot; 14391 var segsByDay = groupSegsByDay(allSegs); // sparse array 14392 return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { 14393 var innerNodes = []; 14394 for (var dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) { 14395 var daySegs = segsByDay[dayIndex]; 14396 if (daySegs) { // sparse array, so might be undefined 14397 var dayStr = formatDayString(dayDates[dayIndex]); 14398 var dateHeaderId = dateHeaderIdRoot + '-' + dayStr; 14399 // append a day header 14400 innerNodes.push(createElement(ListViewHeaderRow, { key: dayStr, cellId: dateHeaderId, dayDate: dayDates[dayIndex], todayRange: todayRange })); 14401 daySegs = sortEventSegs(daySegs, options.eventOrder); 14402 for (var _i = 0, daySegs_1 = daySegs; _i < daySegs_1.length; _i++) { 14403 var seg = daySegs_1[_i]; 14404 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)))); 14405 } 14406 } 14407 } 14408 return (createElement("table", { className: 'fc-list-table ' + theme.getClass('table') }, 14409 createElement("thead", null, 14410 createElement("tr", null, 14411 createElement("th", { scope: "col", id: timeHeaderId }, options.timeHint), 14412 createElement("th", { scope: "col", "aria-hidden": true }), 14413 createElement("th", { scope: "col", id: eventHeaderId }, options.eventHint))), 14414 createElement("tbody", null, innerNodes))); 14415 })); 14416 }; 14417 ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) { 14418 return this.eventRangesToSegs(sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges); 14419 }; 14420 ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) { 14421 var segs = []; 14422 for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) { 14423 var eventRange = eventRanges_1[_i]; 14424 segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges)); 14425 } 14426 return segs; 14427 }; 14428 ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) { 14429 var dateEnv = this.context.dateEnv; 14430 var nextDayThreshold = this.context.options.nextDayThreshold; 14431 var range = eventRange.range; 14432 var allDay = eventRange.def.allDay; 14433 var dayIndex; 14434 var segRange; 14435 var seg; 14436 var segs = []; 14437 for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) { 14438 segRange = intersectRanges(range, dayRanges[dayIndex]); 14439 if (segRange) { 14440 seg = { 14441 component: this, 14442 eventRange: eventRange, 14443 start: segRange.start, 14444 end: segRange.end, 14445 isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(), 14446 isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(), 14447 dayIndex: dayIndex, 14448 }; 14449 segs.push(seg); 14450 // detect when range won't go fully into the next day, 14451 // and mutate the latest seg to the be the end. 14452 if (!seg.isEnd && !allDay && 14453 dayIndex + 1 < dayRanges.length && 14454 range.end < 14455 dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) { 14456 seg.end = range.end; 14457 seg.isEnd = true; 14458 break; 14459 } 14460 } 14461 } 14462 return segs; 14463 }; 14464 return ListView; 14465 }(DateComponent)); 14466 function renderNoEventsInner(hookProps) { 14467 return hookProps.text; 14468 } 14469 function computeDateVars(dateProfile) { 14470 var dayStart = startOfDay(dateProfile.renderRange.start); 14471 var viewEnd = dateProfile.renderRange.end; 14472 var dayDates = []; 14473 var dayRanges = []; 14474 while (dayStart < viewEnd) { 14475 dayDates.push(dayStart); 14476 dayRanges.push({ 14477 start: dayStart, 14478 end: addDays(dayStart, 1), 14479 }); 14480 dayStart = addDays(dayStart, 1); 14481 } 14482 return { dayDates: dayDates, dayRanges: dayRanges }; 14483 } 14484 // Returns a sparse array of arrays, segs grouped by their dayIndex 14485 function groupSegsByDay(segs) { 14486 var segsByDay = []; // sparse array 14487 var i; 14488 var seg; 14489 for (i = 0; i < segs.length; i += 1) { 14490 seg = segs[i]; 14491 (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = [])) 14492 .push(seg); 14493 } 14494 return segsByDay; 14495 } 14496 14497 var OPTION_REFINERS$1 = { 14498 listDayFormat: createFalsableFormatter, 14499 listDaySideFormat: createFalsableFormatter, 14500 noEventsClassNames: identity, 14501 noEventsContent: identity, 14502 noEventsDidMount: identity, 14503 noEventsWillUnmount: identity, 14504 // noEventsText is defined in base options 14505 }; 14506 function createFalsableFormatter(input) { 14507 return input === false ? null : createFormatter(input); 14508 } 14509 14510 var listPlugin = createPlugin({ 14511 optionRefiners: OPTION_REFINERS$1, 14512 views: { 14513 list: { 14514 component: ListView, 14515 buttonTextKey: 'list', 14516 listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' }, // like "January 1, 2016" 14517 }, 14518 listDay: { 14519 type: 'list', 14520 duration: { days: 1 }, 14521 listDayFormat: { weekday: 'long' }, // day-of-week is all we need. full date is probably in headerToolbar 14522 }, 14523 listWeek: { 14524 type: 'list', 14525 duration: { weeks: 1 }, 14526 listDayFormat: { weekday: 'long' }, 14527 listDaySideFormat: { month: 'long', day: 'numeric', year: 'numeric' }, 14528 }, 14529 listMonth: { 14530 type: 'list', 14531 duration: { month: 1 }, 14532 listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have 14533 }, 14534 listYear: { 14535 type: 'list', 14536 duration: { year: 1 }, 14537 listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have 14538 }, 14539 }, 14540 });
14541 14542 var BootstrapTheme$1 = /** @class */ (function (_super) { 14543 __extends(BootstrapTheme, _super); 14544 function BootstrapTheme() { 14545 return _super !== null && _super.apply(this, arguments) || this; 14546 } 14547 return BootstrapTheme; 14548 }(Theme)); 14549 BootstrapTheme$1.prototype.classes = { 14550 root: 'fc-theme-bootstrap', 14551 table: 'table-bordered', 14552 tableCellShaded: 'table-active', 14553 buttonGroup: 'btn-group', 14554 button: 'btn btn-primary', 14555 buttonActive: 'active', 14556 popover: 'popover', 14557 popoverHeader: 'popover-header', 14558 popoverContent: 'popover-body', 14559 }; 14560 BootstrapTheme$1.prototype.baseIconClass = 'fa'; 14561 BootstrapTheme$1.prototype.iconClasses = { 14562 close: 'fa-times', 14563 prev: 'fa-chevron-left', 14564 next: 'fa-chevron-right', 14565 prevYear: 'fa-angle-double-left', 14566 nextYear: 'fa-angle-double-right', 14567 }; 14568 BootstrapTheme$1.prototype.rtlIconClasses = { 14569 prev: 'fa-chevron-right', 14570 next: 'fa-chevron-left', 14571 prevYear: 'fa-angle-double-right', 14572 nextYear: 'fa-angle-double-left', 14573 }; 14574 BootstrapTheme$1.prototype.iconOverrideOption = 'bootstrapFontAwesome'; // TODO: make TS-friendly. move the option-processing into this plugin 14575 BootstrapTheme$1.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome'; 14576 BootstrapTheme$1.prototype.iconOverridePrefix = 'fa-'; 14577 var plugin$1 = createPlugin({ 14578 themeClasses: { 14579 bootstrap: BootstrapTheme$1, 14580 }, 14581 }); 14582 14583 var BootstrapTheme = /** @class */ (function (_super) { 14584 __extends(BootstrapTheme, _super); 14585 function BootstrapTheme() { 14586 return _super !== null && _super.apply(this, arguments) || this; 14587 } 14588 return BootstrapTheme; 14589 }(Theme)); 14590 BootstrapTheme.prototype.classes = { 14591 root: 'fc-theme-bootstrap5', 14592 tableCellShaded: 'fc-theme-bootstrap5-shaded', 14593 buttonGroup: 'btn-group', 14594 button: 'btn btn-primary', 14595 buttonActive: 'active', 14596 popover: 'popover', 14597 popoverHeader: 'popover-header', 14598 popoverContent: 'popover-body', 14599 }; 14600 BootstrapTheme.prototype.baseIconClass = 'bi'; 14601 BootstrapTheme.prototype.iconClasses = { 14602 close: 'bi-x-lg', 14603 prev: 'bi-chevron-left', 14604 next: 'bi-chevron-right', 14605 prevYear: 'bi-chevron-double-left', 14606 nextYear: 'bi-chevron-double-right', 14607 }; 14608 BootstrapTheme.prototype.rtlIconClasses = { 14609 prev: 'bi-chevron-right', 14610 next: 'bi-chevron-left', 14611 prevYear: 'bi-chevron-double-right', 14612 nextYear: 'bi-chevron-double-left', 14613 }; 14614 // wtf 14615 BootstrapTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly 14616 BootstrapTheme.prototype.iconOverrideCustomButtonOption = 'icon'; 14617 BootstrapTheme.prototype.iconOverridePrefix = 'bi-'; 14618 var plugin = createPlugin({ 14619 themeClasses: { 14620 bootstrap5: BootstrapTheme, 14621 }, 14622 }); 14623 14624 // rename this file to options.ts like other packages? 14625 var OPTION_REFINERS = { 14626 googleCalendarApiKey: String, 14627 }; 14628 14629 var EVENT_SOURCE_REFINERS = { 14630 googleCalendarApiKey: String, 14631 googleCalendarId: String, 14632 googleCalendarApiBase: String, 14633 extraParams: identity, 14634 }; 14635 14636 // TODO: expose somehow 14637 var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars'; 14638 var eventSourceDef = { 14639 parseMeta: function (refined) { 14640 var googleCalendarId = refined.googleCalendarId; 14641 if (!googleCalendarId && refined.url) { 14642 googleCalendarId = parseGoogleCalendarId(refined.url); 14643 } 14644 if (googleCalendarId) { 14645 return { 14646 googleCalendarId: googleCalendarId, 14647 googleCalendarApiKey: refined.googleCalendarApiKey, 14648 googleCalendarApiBase: refined.googleCalendarApiBase, 14649 extraParams: refined.extraParams, 14650 }; 14651 } 14652 return null; 14653 },
14654 fetch: function (arg, onSuccess, onFailure) { 14655 var _a = arg.context, dateEnv = _a.dateEnv, options = _a.options; 14656 var meta = arg.eventSource.meta; 14657 var apiKey = meta.googleCalendarApiKey || options.googleCalendarApiKey; 14658 if (!apiKey) { 14659 onFailure({ 14660 message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/', 14661 }); 14662 } 14663 else { 14664 var url = buildUrl(meta); 14665 // TODO: make DRY with json-feed-event-source 14666 var extraParams = meta.extraParams; 14667 var extraParamsObj = typeof extraParams === 'function' ? extraParams() : extraParams; 14668 var requestParams_1 = buildRequestParams(arg.range, apiKey, extraParamsObj, dateEnv); 14669 requestJson('GET', url, requestParams_1, function (body, xhr) { 14670 if (body.error) { 14671 onFailure({ 14672 message: 'Google Calendar API: ' + body.error.message, 14673 errors: body.error.errors, 14674 xhr: xhr, 14675 }); 14676 } 14677 else { 14678 onSuccess({ 14679 rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone), 14680 xhr: xhr, 14681 }); 14682 } 14683 }, function (message, xhr) { 14684 onFailure({ message: message, xhr: xhr }); 14685 }); 14686 } 14687 }, 14688 }; 14689 function parseGoogleCalendarId(url) { 14690 var match; 14691 // detect if the ID was specified as a single string. 14692 // will match calendars like "[email protected]" in addition to person email calendars. 14693 if (/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) { 14694 return url; 14695 } 14696 if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec(url)) || 14697 (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(url))) { 14698 return decodeURIComponent(match[1]); 14699 } 14700 return null; 14701 } 14702 function buildUrl(meta) { 14703 var apiBase = meta.googleCalendarApiBase; 14704 if (!apiBase) { 14705 apiBase = API_BASE; 14706 } 14707 return apiBase + '/' + encodeURIComponent(meta.googleCalendarId) + '/events'; 14708 } 14709 function buildRequestParams(range, apiKey, extraParams, dateEnv) { 14710 var params; 14711 var startStr; 14712 var endStr; 14713 if (dateEnv.canComputeOffset) { 14714 // strings will naturally have offsets, which GCal needs 14715 startStr = dateEnv.formatIso(range.start); 14716 endStr = dateEnv.formatIso(range.end); 14717 } 14718 else { 14719 // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day 14720 // from the UTC day-start to guarantee we're getting all the events 14721 // (start/end will be UTC-coerced dates, so toISOString is okay) 14722 startStr = addDays(range.start, -1).toISOString(); 14723 endStr = addDays(range.end, 1).toISOString(); 14724 } 14725 params = __assign(__assign({}, (extraParams || {})), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 }); 14726 if (dateEnv.timeZone !== 'local') { 14727 params.timeZone = dateEnv.timeZone; 14728 } 14729 return params; 14730 } 14731 function gcalItemsToRawEventDefs(items, gcalTimezone) { 14732 return items.map(function (item) { return gcalItemToRawEventDef(item, gcalTimezone); }); 14733 } 14734 function gcalItemToRawEventDef(item, gcalTimezone) { 14735 var url = item.htmlLink || null; 14736 // make the URLs for each event show times in the correct timezone 14737 if (url && gcalTimezone) { 14738 url = injectQsComponent(url, 'ctz=' + gcalTimezone); 14739 } 14740 return { 14741 id: item.id, 14742 title: item.summary, 14743 start: item.start.dateTime || item.start.date, 14744 end: item.end.dateTime || item.end.date, 14745 url: url, 14746 location: item.location, 14747 description: item.description, 14748 attachments: item.attachments || [], 14749 extendedProps: (item.extendedProperties || {}).shared || {}, 14750 }; 14751 } 14752 // Injects a string like "arg=value" into the querystring of a URL 14753 // TODO: move to a general util file? 14754 function injectQsComponent(url, component) { 14755 // inject it after the querystring but before the fragment 14756 return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) { return (qs ? qs + '&' : '?') + component + hash; }); 14757 } 14758 var googleCalendarPlugin = createPlugin({ 14759 eventSourceDefs: [eventSourceDef], 14760 optionRefiners: OPTION_REFINERS, 14761 eventSourceRefiners: EVENT_SOURCE_REFINERS, 14762 });
14763 14764 globalPlugins.push(interactionPlugin, dayGridPlugin, timeGridPlugin, listPlugin, plugin$1, plugin, googleCalendarPlugin); 14765 14766 exports.BASE_OPTION_DEFAULTS = BASE_OPTION_DEFAULTS; 14767 exports.BASE_OPTION_REFINERS = BASE_OPTION_REFINERS; 14768 exports.BaseComponent = BaseComponent; 14769 exports.BgEvent = BgEvent; 14770 exports.BootstrapTheme = BootstrapTheme$1; 14771 exports.Calendar = Calendar; 14772 exports.CalendarApi = CalendarApi; 14773 exports.CalendarContent = CalendarContent; 14774 exports.CalendarDataManager = CalendarDataManager; 14775 exports.CalendarDataProvider = CalendarDataProvider; 14776 exports.CalendarRoot = CalendarRoot; 14777 exports.Component = Component; 14778 exports.ContentHook = ContentHook; 14779 exports.CustomContentRenderContext = CustomContentRenderContext; 14780 exports.DateComponent = DateComponent; 14781 exports.DateEnv = DateEnv; 14782 exports.DateProfileGenerator = DateProfileGenerator; 14783 exports.DayCellContent = DayCellContent; 14784 exports.DayCellRoot = DayCellRoot; 14785 exports.DayGridView = DayTableView; 14786 exports.DayHeader = DayHeader;
14787 exports.DaySeriesModel = DaySeriesModel; 14788 exports.DayTable = DayTable; 14789 exports.DayTableModel = DayTableModel; 14790 exports.DayTableSlicer = DayTableSlicer; 14791 exports.DayTimeCols = DayTimeCols; 14792 exports.DayTimeColsSlicer = DayTimeColsSlicer; 14793 exports.DayTimeColsView = DayTimeColsView; 14794 exports.DelayedRunner = DelayedRunner; 14795 exports.Draggable = ExternalDraggable; 14796 exports.ElementDragging = ElementDragging; 14797 exports.ElementScrollController = ElementScrollController; 14798 exports.Emitter = Emitter; 14799 exports.EventApi = EventApi; 14800 exports.EventRoot = EventRoot; 14801 exports.EventSourceApi = EventSourceApi; 14802 exports.FeaturefulElementDragging = FeaturefulElementDragging; 14803 exports.Fragment = Fragment; 14804 exports.Interaction = Interaction; 14805 exports.ListView = ListView; 14806 exports.MoreLinkRoot = MoreLinkRoot; 14807 exports.MountHook = MountHook; 14808 exports.NamedTimeZoneImpl = NamedTimeZoneImpl; 14809 exports.NowIndicatorRoot = NowIndicatorRoot; 14810 exports.NowTimer = NowTimer; 14811 exports.PointerDragging = PointerDragging; 14812 exports.PositionCache = PositionCache; 14813 exports.RefMap = RefMap; 14814 exports.RenderHook = RenderHook; 14815 exports.ScrollController = ScrollController; 14816 exports.ScrollResponder = ScrollResponder; 14817 exports.Scroller = Scroller; 14818 exports.SegHierarchy = SegHierarchy; 14819 exports.SimpleScrollGrid = SimpleScrollGrid; 14820 exports.Slicer = Slicer; 14821 exports.Splitter = Splitter; 14822 exports.StandardEvent = StandardEvent; 14823 exports.Table = Table; 14824 exports.TableDateCell = TableDateCell; 14825 exports.TableDowCell = TableDowCell; 14826 exports.TableView = TableView; 14827 exports.Theme = Theme; 14828 exports.ThirdPartyDraggable = ThirdPartyDraggable; 14829 exports.TimeCols = TimeCols; 14830 exports.TimeColsSlatsCoords = TimeColsSlatsCoords; 14831 exports.TimeColsView = TimeColsView; 14832 exports.ViewApi = ViewApi; 14833 exports.ViewContextType = ViewContextType; 14834 exports.ViewRoot = ViewRoot; 14835 exports.WeekNumberRoot = WeekNumberRoot; 14836 exports.WindowScrollController = WindowScrollController; 14837 exports.addDays = addDays; 14838 exports.addDurations = addDurations; 14839 exports.addMs = addMs; 14840 exports.addWeeks = addWeeks; 14841 exports.allowContextMenu = allowContextMenu; 14842 exports.allowSelection = allowSelection; 14843 exports.applyMutationToEventStore = applyMutationToEventStore; 14844 exports.applyStyle = applyStyle; 14845 exports.applyStyleProp = applyStyleProp; 14846 exports.asCleanDays = asCleanDays; 14847 exports.asRoughMinutes = asRoughMinutes; 14848 exports.asRoughMs = asRoughMs; 14849 exports.asRoughSeconds = asRoughSeconds; 14850 exports.binarySearch = binarySearch; 14851 exports.buildClassNameNormalizer = buildClassNameNormalizer; 14852 exports.buildDayRanges = buildDayRanges; 14853 exports.buildDayTableModel = buildDayTableModel; 14854 exports.buildEntryKey = buildEntryKey; 14855 exports.buildEventApis = buildEventApis; 14856 exports.buildEventRangeKey = buildEventRangeKey; 14857 exports.buildHashFromArray = buildHashFromArray; 14858 exports.buildIsoString = buildIsoString; 14859 exports.buildNavLinkAttrs = buildNavLinkAttrs; 14860 exports.buildSegCompareObj = buildSegCompareObj; 14861 exports.buildSegTimeText = buildSegTimeText; 14862 exports.buildSlatMetas = buildSlatMetas; 14863 exports.buildTimeColsModel = buildTimeColsModel; 14864 exports.collectFromHash = collectFromHash; 14865 exports.combineEventUis = combineEventUis; 14866 exports.compareByFieldSpec = compareByFieldSpec; 14867 exports.compareByFieldSpecs = compareByFieldSpecs; 14868 exports.compareNumbers = compareNumbers; 14869 exports.compareObjs = compareObjs; 14870 exports.computeEarliestSegStart = computeEarliestSegStart; 14871 exports.computeEdges = computeEdges; 14872 exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat; 14873 exports.computeHeightAndMargins = computeHeightAndMargins; 14874 exports.computeInnerRect = computeInnerRect; 14875 exports.computeRect = computeRect; 14876 exports.computeSegDraggable = computeSegDraggable; 14877 exports.computeSegEndResizable = computeSegEndResizable; 14878 exports.computeSegStartResizable = computeSegStartResizable; 14879 exports.computeShrinkWidth = computeShrinkWidth; 14880 exports.computeSmallestCellWidth = computeSmallestCellWidth; 14881 exports.computeVisibleDayRange = computeVisibleDayRange; 14882 exports.config = config; 14883 exports.constrainPoint = constrainPoint; 14884 exports.createAriaClickAttrs = createAriaClickAttrs; 14885 exports.createContext = createContext; 14886 exports.createDuration = createDuration; 14887 exports.createElement = createElement; 14888 exports.createEmptyEventStore = createEmptyEventStore; 14889 exports.createEventInstance = createEventInstance; 14890 exports.createEventUi = createEventUi; 14891 exports.createFormatter = createFormatter; 14892 exports.createPlugin = createPlugin; 14893 exports.createPortal = createPortal; 14894 exports.createRef = createRef; 14895 exports.diffDates = diffDates; 14896 exports.diffDayAndTime = diffDayAndTime; 14897 exports.diffDays = diffDays; 14898 exports.diffPoints = diffPoints; 14899 exports.diffWeeks = diffWeeks; 14900 exports.diffWholeDays = diffWholeDays; 14901 exports.diffWholeWeeks = diffWholeWeeks; 14902 exports.disableCursor = disableCursor; 14903 exports.elementClosest = elementClosest; 14904 exports.elementMatches = elementMatches; 14905 exports.enableCursor = enableCursor; 14906 exports.eventTupleToStore = eventTupleToStore; 14907 exports.filterEventStoreDefs = filterEventStoreDefs; 14908 exports.filterHash = filterHash; 14909 exports.findDirectChildren = findDirectChildren; 14910 exports.findElements = findElements; 14911 exports.flexibleCompare = flexibleCompare; 14912 exports.flushSync = flushSync; 14913 exports.formatDate = formatDate; 14914 exports.formatDayString = formatDayString; 14915 exports.formatIsoTimeString = formatIsoTimeString; 14916 exports.formatRange = formatRange; 14917 exports.getAllowYScrolling = getAllowYScrolling; 14918 exports.getCanVGrowWithinCell = getCanVGrowWithinCell; 14919 exports.getClippingParents = getClippingParents; 14920 exports.getDateMeta = getDateMeta; 14921 exports.getDayClassNames = getDayClassNames; 14922 exports.getDefaultEventEnd = getDefaultEventEnd; 14923 exports.getElRoot = getElRoot; 14924 exports.getElSeg = getElSeg; 14925 exports.getEntrySpanEnd = getEntrySpanEnd; 14926 exports.getEventClassNames = getEventClassNames; 14927 exports.getEventTargetViaRoot = getEventTargetViaRoot; 14928 exports.getIsRtlScrollbarOnLeft = getIsRtlScrollbarOnLeft; 14929 exports.getRectCenter = getRectCenter; 14930 exports.getRelevantEvents = getRelevantEvents; 14931 exports.getScrollGridClassNames = getScrollGridClassNames;
14932 exports.getScrollbarWidths = getScrollbarWidths; 14933 exports.getSectionClassNames = getSectionClassNames; 14934 exports.getSectionHasLiquidHeight = getSectionHasLiquidHeight; 14935 exports.getSegAnchorAttrs = getSegAnchorAttrs; 14936 exports.getSegMeta = getSegMeta; 14937 exports.getSlotClassNames = getSlotClassNames; 14938 exports.getStickyFooterScrollbar = getStickyFooterScrollbar; 14939 exports.getStickyHeaderDates = getStickyHeaderDates; 14940 exports.getUnequalProps = getUnequalProps; 14941 exports.getUniqueDomId = getUniqueDomId; 14942 exports.globalLocales = globalLocales; 14943 exports.globalPlugins = globalPlugins; 14944 exports.greatestDurationDenominator = greatestDurationDenominator; 14945 exports.groupIntersectingEntries = groupIntersectingEntries; 14946 exports.guid = guid; 14947 exports.hasBgRendering = hasBgRendering; 14948 exports.hasShrinkWidth = hasShrinkWidth; 14949 exports.identity = identity; 14950 exports.interactionSettingsStore = interactionSettingsStore; 14951 exports.interactionSettingsToStore = interactionSettingsToStore; 14952 exports.intersectRanges = intersectRanges; 14953 exports.intersectRects = intersectRects; 14954 exports.intersectSpans = intersectSpans; 14955 exports.isArraysEqual = isArraysEqual; 14956 exports.isColPropsEqual = isColPropsEqual; 14957 exports.isDateSelectionValid = isDateSelectionValid; 14958 exports.isDateSpansEqual = isDateSpansEqual; 14959 exports.isInt = isInt; 14960 exports.isInteractionValid = isInteractionValid; 14961 exports.isMultiDayRange = isMultiDayRange; 14962 exports.isPropsEqual = isPropsEqual; 14963 exports.isPropsValid = isPropsValid; 14964 exports.isValidDate = isValidDate; 14965 exports.joinSpans = joinSpans; 14966 exports.listenBySelector = listenBySelector; 14967 exports.mapHash = mapHash; 14968 exports.memoize = memoize; 14969 exports.memoizeArraylike = memoizeArraylike; 14970 exports.memoizeHashlike = memoizeHashlike; 14971 exports.memoizeObjArg = memoizeObjArg; 14972 exports.mergeEventStores = mergeEventStores; 14973 exports.multiplyDuration = multiplyDuration; 14974 exports.padStart = padStart; 14975 exports.parseBusinessHours = parseBusinessHours; 14976 exports.parseClassNames = parseClassNames; 14977 exports.parseDragMeta = parseDragMeta; 14978 exports.parseEventDef = parseEventDef; 14979 exports.parseFieldSpecs = parseFieldSpecs; 14980 exports.parseMarker = parse; 14981 exports.pointInsideRect = pointInsideRect; 14982 exports.preventContextMenu = preventContextMenu; 14983 exports.preventDefault = preventDefault; 14984 exports.preventSelection = preventSelection; 14985 exports.rangeContainsMarker = rangeContainsMarker; 14986 exports.rangeContainsRange = rangeContainsRange; 14987 exports.rangesEqual = rangesEqual; 14988 exports.rangesIntersect = rangesIntersect; 14989 exports.refineEventDef = refineEventDef; 14990 exports.refineProps = refineProps; 14991 exports.removeElement = removeElement; 14992 exports.removeExact = removeExact; 14993 exports.render = render; 14994 exports.renderChunkContent = renderChunkContent; 14995 exports.renderFill = renderFill; 14996 exports.renderMicroColGroup = renderMicroColGroup; 14997 exports.renderScrollShim = renderScrollShim; 14998 exports.requestJson = requestJson; 14999 exports.sanitizeShrinkWidth = sanitizeShrinkWidth; 15000 exports.setElSeg = setElSeg; 15001 exports.setRef = setRef; 15002 exports.sliceEventStore = sliceEventStore; 15003 exports.sliceEvents = sliceEvents; 15004 exports.sortEventSegs = sortEventSegs; 15005 exports.startOfDay = startOfDay; 15006 exports.translateRect = translateRect; 15007 exports.triggerDateSelect = triggerDateSelect; 15008 exports.unmountComponentAtNode = unmountComponentAtNode; 15009 exports.unpromisify = unpromisify; 15010 exports.version = version; 15011 exports.whenTransitionDone = whenTransitionDone; 15012 exports.wholeDivideDurations = wholeDivideDurations; 15013
15014 Object.defineProperty(exports, '__esModule', { value: true }); 15015 15016 return exports; 15017 15018}({}));
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.