vendor: 4,461 bytes, lines 1-61
1/*! 2FullCalendar v5.10.1 3Docs & License: https://fullcalendar.io/ 4(c) 2021 Adam Shaw 5*/ 6var FullCalendar = (function (exports) { 7 'use strict'; 8 9 /*! ***************************************************************************** 10 Copyright (c) Microsoft Corporation. 11 12 Permission to use, copy, modify, and/or distribute this software for any 13 purpose with or without fee is hereby granted. 14 15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 16 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 17 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 18 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 19 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 PERFORMANCE OF THIS SOFTWARE. 22 ***************************************************************************** */ 23 /* global Reflect, Promise */ 24 25 var extendStatics = function(d, b) { 26 extendStatics = Object.setPrototypeOf || 27 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 28 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 29 return extendStatics(d, b); 30 }; 31 32 function __extends(d, b) { 33 if (typeof b !== "function" && b !== null) 34 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 35 extendStatics(d, b); 36 function __() { this.constructor = d; } 37 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 38 } 39 40 var __assign = function() { 41 __assign = Object.assign || function __assign(t) { 42 for (var s, i = 1, n = arguments.length; i < n; i++) { 43 s = arguments[i]; 44 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 45 } 46 return t; 47 }; 48 return __assign.apply(this, arguments); 49 }; 50 51 function __spreadArray(to, from, pack) { 52 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 53 if (ar || !(i in from)) { 54 if (!ar) ar = Array.prototype.slice.call(from, 0, i); 55 ar[i] = from[i]; 56 } 57 } 58 return to.concat(ar || from); 59 } 60 61 var n,u,i$1,t,o,r$1={},f$1=[],e$1=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function c$1(n,l){for(var u in l)n[u]=l[u];return n}function s(n){var l=n.parentNode;l&&l.removeChild(n);}function a$1(n,l,u){var i,t,o,r=arguments,f={};for(o in l)"key"==o?i=l[o]:"ref"==o?t=l[o]:f[o]=l[o];if(arguments.length>3)for(u=[u],o=3;o<arguments.length;o++)u.push(r[o]);if(null!=u&&(f.children=u),"function"==typeof n&&null!=n.defaultProps)for(o in n.defaultProps)void 0===f[o]&&(f[o]=n.defaultProps[o]);return v$1(n,f,i,t,null)}function v$1(l,u,i,t,o){var r={type:l,props:u,key:i,ref:t,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++n.__v:o};return null!=n.vnode&&n.vnode(r),r}function h(){return {current:null}}function y(n){return n.children}function p(n,l){this.props=n,this.context=l;}function d(n,l){if(null==l)return n.__?d(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?d(n):null}function _(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return _(n)}}function k(l){(!l.__d&&(l.__d=!0)&&u.push(l)&&!b$1.__r++||t!==n.debounceRendering)&&((t=n.debounceRendering)||i$1)(b$1);}function b$1(){for(var n;b$1.__r=u.length;)n=u.sort(function(n,l){return n.__v.__b-l.__v.__b}),u=[],n.some(function(n){var l,u,i,t,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=c$1({},t)).__v=t.__v+1,I$1(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?d(t):o,t.__h),T$1(u,t),t.__e!=o&&_(t)));});}function m(n,l,u,i,t,o,e,c,s,a){var h,p,_,k,b,m,w,A=i&&i.__k||f$1,P=A.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(k=u.__k[h]=null==(k=l[h])||"boolean"==typeof k?null:"string"==typeof k||"number"==typeof k||"bigint"==typeof k?v$1(null,k,null,null,k):Array.isArray(k)?v$1(y,{children:k},null,null,null):k.__b>
vendor: 7,710 bytes, line 61
610?v$1(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(_=A[h])||_&&k.key==_.key&&k.type===_.type)A[h]=void 0;else for(p=0;p<P;p++){if((_=A[p])&&k.key==_.key&&k.type===_.type){A[p]=void 0;break}_=null;}I$1(n,k,_=_||r$1,t,o,e,c,s,a),b=k.__e,(p=k.ref)&&_.ref!=p&&(w||(w=[]),_.ref&&w.push(_.ref,null,k),w.push(p,k.__c||b,k)),null!=b?(null==m&&(m=b),"function"==typeof k.type&&null!=k.__k&&k.__k===_.__k?k.__d=s=g$1(k,s,n):s=x$1(n,k,_,A,b,s),a||"option"!==u.type?"function"==typeof u.type&&(u.__d=s):n.value=""):s&&_.__e==s&&s.parentNode!=n&&(s=d(_));}for(u.__e=m,h=P;h--;)null!=A[h]&&("function"==typeof u.type&&null!=A[h].__e&&A[h].__e==u.__d&&(u.__d=d(i,h+1)),L$1(A[h],A[h]));if(w)for(h=0;h<w.length;h++)z(w[h],w[++h],w[++h]);}function g$1(n,l,u){var i,t;for(i=0;i<n.__k.length;i++)(t=n.__k[i])&&(t.__=n,l="function"==typeof t.type?g$1(t,l,u):x$1(u,t,t,n.__k,t.__e,l));return l}function w$1(n,l){return l=l||[],null==n||"boolean"==typeof n||(Array.isArray(n)?n.some(function(n){w$1(n,l);}):l.push(n)),l}function x$1(n,l,u,i,t,o){var r,f,e;if(void 0!==l.__d)r=l.__d,l.__d=void 0;else if(null==u||t!=o||null==t.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(t),r=null;else {for(f=o,e=0;(f=f.nextSibling)&&e<i.length;e+=2)if(f==t)break n;n.insertBefore(t,o),r=o;}return void 0!==r?r:t.nextSibling}function A$1(n,l,u,i,t){var o;for(o in u)"children"===o||"key"===o||o in l||C$1(n,o,null,u[o],i);for(o in l)t&&"function"!=typeof l[o]||"children"===o||"key"===o||"value"===o||"checked"===o||u[o]===l[o]||C$1(n,o,l[o],u[o],i);}function P$1(n,l,u){"-"===l[0]?n.setProperty(l,u):n[l]=null==u?"":"number"!=typeof u||e$1.test(l)?u:u+"px";}function C$1(n,l,u,i,t){var o;n:if("style"===l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof i&&(n.style.cssText=i=""),i)for(l in i)u&&l in u||P$1(n.style,l,"");if(u)for(l in u)i&&u[l]===i[l]||P$1(n.style,l,u[l]);}else if("o"===l[0]&&"n"===l[1])o=l!==(l=l.replace(/Capture$/,"")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?i||n.addEventListener(l,o?H$1:$$1,o):n.removeEventListener(l,o?H$1:$$1,o);else if("dangerouslySetInnerHTML"!==l){if(t)l=l.replace(/xlink[H:h]/,"h").replace(/sName$/,"s");else if("href"!==l&&"list"!==l&&"form"!==l&&"tabIndex"!==l&&"download"!==l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null!=u&&(!1!==u||"a"===l[0]&&"r"===l[1])?n.setAttribute(l,u):n.removeAttribute(l));}}function $$1(l){this.l[l.type+!1](n.event?n.event(l):l);}function H$1(l){this.l[l.type+!0](n.event?n.event(l):l);}function I$1(l,u,i,t,o,r,f,e,s){var a,v,h,d,_,k,b,g,w,x,A,P=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(s=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(a=n.__b)&&a(u);try{n:if("function"==typeof P){if(g=u.props,w=(a=P.contextType)&&t[a.__c],x=a?w?w.props.value:a.__:t,i.__c?b=(v=u.__c=i.__c).__=v.__E:("prototype"in P&&P.prototype.render?u.__c=v=new P(g,x):(u.__c=v=new p(g,x),v.constructor=P,v.render=M$1),w&&w.sub(v),v.props=g,v.state||(v.state={}),v.context=x,v.__n=t,h=v.__d=!0,v.__h=[]),null==v.__s&&(v.__s=v.state),null!=P.getDerivedStateFromProps&&(v.__s==v.state&&(v.__s=c$1({},v.__s)),c$1(v.__s,P.getDerivedStateFromProps(g,v.__s))),d=v.props,_=v.state,h)null==P.getDerivedStateFromProps&&null!=v.componentWillMount&&v.componentWillMount(),null!=v.componentDidMount&&v.__h.push(v.componentDidMount);else {if(null==P.getDerivedStateFromProps&&g!==d&&null!=v.componentWillReceiveProps&&v.componentWillReceiveProps(g,x),!v.__e&&null!=v.shouldComponentUpdate&&!1===v.shouldComponentUpdate(g,v.__s,x)||u.__v===i.__v){v.props=g,v.state=v.__s,u.__v!==i.__v&&(v.__d=!1),v.__v=u,u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u);}),v.__h.length&&f.push(v);break n}null!=v.componentWillUpdate&&v.componentWillUpdate(g,v.__s,x),null!=v.componentDidUpdate&&v.__h.push(function(){v.componentDidUpdate(d,_,k);});}v.context=x,v.props=g,v.state=v.__s,(a=n.__r)&&a(u),v.__d=!1,v.__v=u,v.__P=l,a=v.render(v.props,v.state,v.context),v.state=v.__s,null!=v.getChildContext&&(t=c$1(c$1({},t),v.getChildContext())),h||null==v.getSnapshotBeforeUpdate||(k=v.getSnapshotBeforeUpdate(d,_)),A=null!=a&&a.type===y&&null==a.key?a.props.children:a,m(l,Array.isArray(A)?A:[A],u,i,t,o,r,f,e,s),v.base=u.__e,u.__h=null,v.__h.length&&f.push(v),b&&(v.__E=v.__=null),v.__e=!1;}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=j$2(i.__e,u,i,t,o,r,f,s);(a=n.diffed)&&a(u);}catch(l){u.__v=null,(s||null!=r)&&(u.__e=e,u.__h=!!s,r[r.indexOf(e)]=null),n.__e(l,u,i);}}function T$1(l,u){n.__c&&n.__c(u,l),l.some(function(u){try{l=u.__h,u.__h=[],l.some(function(n){n.call(u);});}catch(l){n.__e(l,u.__v);}});}function j$2(n,l,u,i,t,o,e,c){var a,v,h,y,p=u.props,d=l.props,_=l.type,k=0;if("svg"===_&&(t=!0),null!=o)for(;k<o.length;k++)if((a=o[k])&&(a===n||(_?a.localName==_:3==a.nodeType))){n=a,o[k]=null;break}if(null==n){if(null===_)return document.createTextNode(d);n=t?document.createElementNS("http://www.w3.org/2000/svg",_):document.createElement(_,d.is&&d),o=null,c=!1;}if(null===_)p===d||c&&n.data===d||(n.data=d);else {if(o=o&&f$1.slice.call(n.childNodes),v=(p=u.props||r$1).dangerouslySetInnerHTML,h=d.dangerouslySetInnerHTML,!c){if(null!=o)for(p={},y=0;y<n.attributes.length;y++)p[n.attributes[y].name]=n.attributes[y].value;(h||v)&&(h&&(v&&h.__html==v.__html||h.__html===n.innerHTML)||(n.innerHTML=h&&h.__html||""));}if(A$1(n,d,p,t,c),h)l.__k=[];else if(k=l.props.children,m(n,Array.isArray(k)?k:[k],l,u,i,t&&"foreignObject"!==_,o,e,n.firstChild,c),null!=o)for(k=o.length;k--;)null!=o[k]&&s(o[k]);c||("value"in d&&void 0!==(k=d.value)&&(k!==n.value||"progress"===_&&!k)&&C$1(n,"value",k,p.value,!1),"checked"in d&&void 0!==(k=d.checked)&&k!==n.checked&&C$1(n,"checked",k,p.checked,!1));}return n}function z(l,u,i){try{"function"==typeof l?l(u):l.current=u;}catch(l){n.__e(l,i);}}function L$1(l,u,i){var t,o,r;if(n.unmount&&n.unmount(l),(t=l.ref)&&(t.current&&t.current!==l.__e||z(t,null,u)),i||"function"==typeof l.type||(i=null!=(o=l.__e)),l.__e=l.__d=void 0,null!=(t=l.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount();}catch(l){n.__e(l,u);}t.base=t.__P=null;}if(t=l.__k)for(r=0;r<t.length;r++)t[r]&&L$1(t[r],u,i);null!=o&&s(o);}function M$1(n,l,u){return this.constructor(n,u)}function N(l,u,i){var t,o,e;n.__&&n.__(l,u),o=(t="function"==typeof i)?null:i&&i.__k||u.__k,e=[],I$1(u,l=(!t&&i||u).__k=a$1(y,null,[l]),o||r$1,r$1,void 0!==u.ownerSVGElement,!t&&i?[i]:o?null:u.firstChild?f$1.slice.call(u.childNodes):null,e,!t&&i?i:o?o.__e:u.firstChild,t),T$1(e,l);}function q(n,l){var u={__c:l="__cC"+o++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(k);},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n);};}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n={__e:function(n,l){for(var u,i,t;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return u.__E=u}catch(l){n=l;}throw n},__v:0},p.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=c$1({},this.state),"function"==typeof n&&(n=n(c$1({},u),this.props)),n&&c$1(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),k(this));},p.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),k(this));},p.prototype.render=y,u=[],i$1="function"==typeof Promise?Promise.prototype.then.bind(Prom
vendor: 5,073 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 flushToDom: flushToDom$1, 81 unmountComponentAtNode: unmountComponentAtNode$1, 82 }; 83 } 84 // HACKS... 85 // TODO: lock version 86 // TODO: link gh issues 87 function flushToDom$1() { 88 var oldDebounceRendering = n.debounceRendering; // orig 89 var callbackQ = []; 90 function execCallbackSync(callback) { 91 callbackQ.push(callback); 92 } 93 n.debounceRendering = execCallbackSync; 94 N(a$1(FakeComponent, {}), document.createElement('div')); 95 while (callbackQ.length) { 96 callbackQ.shift()(); 97 } 98 n.debounceRendering = oldDebounceRendering; 99 } 100 var FakeComponent = /** @class */ (function (_super) { 101 __extends(FakeComponent, _super); 102 function FakeComponent() { 103 return _super !== null && _super.apply(this, arguments) || this; 104 } 105 FakeComponent.prototype.render = function () { return a$1('div', {}); }; 106 FakeComponent.prototype.componentDidMount = function () { this.setState({}); }; 107 return FakeComponent; 108 }(p)); 109 function createContext$1(defaultValue) { 110 var ContextType = q(defaultValue); 111 var origProvider = ContextType.Provider; 112 ContextType.Provider = function () { 113 var _this = this; 114 var isNew = !this.getChildContext; 115 var children = origProvider.apply(this, arguments); // eslint-disable-line prefer-rest-params 116 if (isNew) { 117 var subs_1 = []; 118 this.shouldComponentUpdate = function (_props) { 119 if (_this.props.value !== _props.value) { 120 subs_1.forEach(function (c) { 121 c.context = _props.value; 122 c.forceUpdate(); 123 }); 124 } 125 }; 126 this.sub = function (c) { 127 subs_1.push(c); 128 var old = c.componentWillUnmount; 129 c.componentWillUnmount = function () { 130 subs_1.splice(subs_1.indexOf(c), 1); 131 old && old.call(c); 132 }; 133 }; 134 } 135 return children; 136 }; 137 return ContextType; 138 } 139 function unmountComponentAtNode$1(node) { 140 N(null, node); 141 } 142 143 // no public types yet. when there are, export from: 144 // import {} from './api-type-deps' 145 var EventSourceApi = /** @class */ (function () { 146 function EventSourceApi(context, internalEventSource) { 147 this.context = context; 148 this.internalEventSource = internalEventSource; 149 } 150 EventSourceApi.prototype.remove = function () { 151 this.context.dispatch({
152 type: 'REMOVE_EVENT_SOURCE', 153 sourceId: this.internalEventSource.sourceId, 154 }); 155 }; 156 EventSourceApi.prototype.refetch = function () { 157 this.context.dispatch({ 158 type: 'FETCH_EVENT_SOURCES', 159 sourceIds: [this.internalEventSource.sourceId], 160 isRefetch: true, 161 }); 162 }; 163 Object.defineProperty(EventSourceApi.prototype, "id", { 164 get: function () { 165 return this.internalEventSource.publicId; 166 }, 167 enumerable: false, 168 configurable: true 169 }); 170 Object.defineProperty(EventSourceApi.prototype, "url", { 171 get: function () { 172 return this.internalEventSource.meta.url; 173 }, 174 enumerable: false, 175 configurable: true 176 }); 177 Object.defineProperty(EventSourceApi.prototype, "format", { 178 get: function () { 179 return this.internalEventSource.meta.format; // TODO: bad. not guaranteed 180 }, 181 enumerable: false, 182 configurable: true 183 }); 184 return EventSourceApi; 185 }()); 186 187 function removeElement(el) { 188 if (el.parentNode) { 189 el.parentNode.removeChild(el); 190 } 191 } 192 // Querying 193 // ---------------------------------------------------------------------------------------------------------------- 194 function elementClosest(el, selector) { 195 if (el.closest) { 196 return el.closest(selector); 197 // really bad fallback for IE 198 // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest 199 } 200 if (!document.documentElement.contains(el)) { 201 return null; 202 } 203 do { 204 if (elementMatches(el, selector)) { 205 return el; 206 } 207 el = (el.parentElement || el.parentNode); 208 } while (el !== null && el.nodeType === 1); 209 return null; 210 } 211 function elementMatches(el, selector) { 212 var method = el.matches || el.matchesSelector || el.msMatchesSelector; 213 return method.call(el, selector); 214 } 215 // accepts multiple subject els 216 // returns a real array. good for methods like forEach 217 // TODO: accept the document 218 function findElements(container, selector) { 219 var containers = container instanceof HTMLElement ? [container] : container; 220 var allMatches = []; 221 for (var i = 0; i < containers.length; i += 1) { 222 var matches = containers[i].querySelectorAll(selector); 223 for (var j = 0; j < matches.length; j += 1) { 224 allMatches.push(matches[j]); 225 } 226 } 227 return allMatches; 228 } 229 // accepts multiple subject els 230 // only queries direct child elements // TODO: rename to findDirectChildren! 231 function findDirectChildren(parent, selector) { 232 var parents = parent instanceof HTMLElement ? [parent] : parent; 233 var allMatches = []; 234 for (var i = 0; i < parents.length; i += 1) { 235 var childNodes = parents[i].children; // only ever elements 236 for (var j = 0; j < childNodes.length; j += 1) { 237 var childNode = childNodes[j]; 238 if (!selector || elementMatches(childNode, selector)) { 239 allMatches.push(childNode); 240 } 241 } 242 } 243 return allMatches; 244 } 245 // Style 246 // ---------------------------------------------------------------------------------------------------------------- 247 var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i; 248 function applyStyle(el, props) { 249 for (var propName in props) { 250 applyStyleProp(el, propName, props[propName]); 251 } 252 } 253 function applyStyleProp(el, name, val) { 254 if (val == null) { 255 el.style[name] = ''; 256 } 257 else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) { 258 el.style[name] = val + "px"; 259 } 260 else { 261 el.style[name] = val; 262 } 263 } 264 // Event Handling 265 // ---------------------------------------------------------------------------------------------------------------- 266 // if intercepting bubbled events at the document/window/body level, 267 // and want to see originating element (the 'target'), use this util instead 268 // of `ev.target` because it goes within web-component boundaries. 269 function getEventTargetViaRoot(ev) { 270 var _a, _b; 271 return (_b = (_a = ev.composedPath) === null || _a === void 0 ? void 0 : _a.call(ev)[0]) !== null && _b !== void 0 ? _b : ev.target; 272 } 273 // Shadow DOM consuderations 274 // ---------------------------------------------------------------------------------------------------------------- 275 function getElRoot(el) { 276 return el.getRootNode ? el.getRootNode() : document; 277 } 278 // Unique ID for DOM attribute 279 var guid$1 = 0; 280 function getUniqueDomId() { 281 guid$1 += 1; 282 return 'fc-dom-' + guid$1; 283 } 284 285 // Stops a mouse/touch event from doing it's native browser action 286 function preventDefault(ev) { 287 ev.preventDefault(); 288 } 289 // Event Delegation 290 // ---------------------------------------------------------------------------------------------------------------- 291 function buildDelegationHandler(selector, handler) { 292 return function (ev) {
vendor: 16,162 bytes, lines 293-749
293 var matchedChild = elementClosest(ev.target, selector); 294 if (matchedChild) { 295 handler.call(matchedChild, ev, matchedChild); 296 } 297 }; 298 } 299 function listenBySelector(container, eventType, selector, handler) { 300 var attachedHandler = buildDelegationHandler(selector, handler); 301 container.addEventListener(eventType, attachedHandler); 302 return function () { 303 container.removeEventListener(eventType, attachedHandler); 304 }; 305 } 306 function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) { 307 var currentMatchedChild; 308 return listenBySelector(container, 'mouseover', selector, function (mouseOverEv, matchedChild) { 309 if (matchedChild !== currentMatchedChild) { 310 currentMatchedChild = matchedChild; 311 onMouseEnter(mouseOverEv, matchedChild); 312 var realOnMouseLeave_1 = function (mouseLeaveEv) { 313 currentMatchedChild = null; 314 onMouseLeave(mouseLeaveEv, matchedChild); 315 matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1); 316 }; 317 // listen to the next mouseleave, and then unattach 318 matchedChild.addEventListener('mouseleave', realOnMouseLeave_1); 319 } 320 }); 321 } 322 // Animation 323 // ---------------------------------------------------------------------------------------------------------------- 324 var transitionEventNames = [ 325 'webkitTransitionEnd', 326 'otransitionend', 327 'oTransitionEnd', 328 'msTransitionEnd', 329 'transitionend', 330 ]; 331 // triggered only when the next single subsequent transition finishes 332 function whenTransitionDone(el, callback) { 333 var realCallback = function (ev) { 334 callback(ev); 335 transitionEventNames.forEach(function (eventName) { 336 el.removeEventListener(eventName, realCallback); 337 }); 338 }; 339 transitionEventNames.forEach(function (eventName) { 340 el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes 341 }); 342 } 343 // ARIA workarounds 344 // ---------------------------------------------------------------------------------------------------------------- 345 function createAriaClickAttrs(handler) { 346 return __assign({ onClick: handler }, createAriaKeyboardAttrs(handler)); 347 } 348 function createAriaKeyboardAttrs(handler) { 349 return { 350 tabIndex: 0, 351 onKeyDown: function (ev) { 352 if (ev.key === 'Enter' || ev.key === ' ') { 353 handler(ev); 354 ev.preventDefault(); // if space, don't scroll down page 355 } 356 }, 357 }; 358 } 359 360 var guidNumber = 0; 361 function guid() { 362 guidNumber += 1; 363 return String(guidNumber); 364 } 365 /* FullCalendar-specific DOM Utilities 366 ----------------------------------------------------------------------------------------------------------------------*/ 367 // Make the mouse cursor express that an event is not allowed in the current area 368 function disableCursor() { 369 document.body.classList.add('fc-not-allowed'); 370 } 371 // Returns the mouse cursor to its original look 372 function enableCursor() { 373 document.body.classList.remove('fc-not-allowed'); 374 } 375 /* Selection 376 ----------------------------------------------------------------------------------------------------------------------*/ 377 function preventSelection(el) { 378 el.classList.add('fc-unselectable'); 379 el.addEventListener('selectstart', preventDefault); 380 } 381 function allowSelection(el) { 382 el.classList.remove('fc-unselectable'); 383 el.removeEventListener('selectstart', preventDefault); 384 } 385 /* Context Menu 386 ----------------------------------------------------------------------------------------------------------------------*/ 387 function preventContextMenu(el) { 388 el.addEventListener('contextmenu', preventDefault); 389 } 390 function allowContextMenu(el) { 391 el.removeEventListener('contextmenu', preventDefault); 392 } 393 function parseFieldSpecs(input) { 394 var specs = []; 395 var tokens = []; 396 var i; 397 var token; 398 if (typeof input === 'string') { 399 tokens = input.split(/\s*,\s*/); 400 } 401 else if (typeof input === 'function') { 402 tokens = [input]; 403 } 404 else if (Array.isArray(input)) { 405 tokens = input; 406 } 407 for (i = 0; i < tokens.length; i += 1) { 408 token = tokens[i]; 409 if (typeof token === 'string') { 410 specs.push(token.charAt(0) === '-' ? 411 { field: token.substring(1), order: -1 } : 412 { field: token, order: 1 }); 413 } 414 else if (typeof token === 'function') { 415 specs.push({ func: token }); 416 } 417 } 418 return specs; 419 } 420 function compareByFieldSpecs(obj0, obj1, fieldSpecs) { 421 var i; 422 var cmp; 423 for (i = 0; i < fieldSpecs.length; i += 1) { 424 cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]); 425 if (cmp) { 426 return cmp; 427 } 428 } 429 return 0; 430 } 431 function compareByFieldSpec(obj0, obj1, fieldSpec) { 432 if (fieldSpec.func) { 433 return fieldSpec.func(obj0, obj1); 434 } 435 return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field]) 436 * (fieldSpec.order || 1); 437 } 438 function flexibleCompare(a, b) { 439 if (!a && !b) { 440 return 0; 441 } 442 if (b == null) { 443 return -1; 444 } 445 if (a == null) { 446 return 1; 447 } 448 if (typeof a === 'string' || typeof b === 'string') { 449 return String(a).localeCompare(String(b)); 450 } 451 return a - b; 452 } 453 /* String Utilities 454 ----------------------------------------------------------------------------------------------------------------------*/ 455 function padStart(val, len) { 456 var s = String(val); 457 return '000'.substr(0, len - s.length) + s; 458 } 459 function formatWithOrdinals(formatter, args, fallbackText) { 460 if (typeof formatter === 'function') { 461 return formatter.apply(void 0, args); 462 } 463 if (typeof formatter === 'string') { // non-blank string 464 return args.reduce(function (str, arg, index) { return (str.replace('$' + index, arg || '')); }, formatter); 465 } 466 return fallbackText; 467 } 468 /* Number Utilities 469 ----------------------------------------------------------------------------------------------------------------------*/ 470 function compareNumbers(a, b) { 471 return a - b; 472 } 473 function isInt(n) { 474 return n % 1 === 0; 475 } 476 /* FC-specific DOM dimension stuff 477 ----------------------------------------------------------------------------------------------------------------------*/ 478 function computeSmallestCellWidth(cellEl) { 479 var allWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-frame'); 480 var contentWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-cushion'); 481 if (!allWidthEl) { 482 throw new Error('needs fc-scrollgrid-shrink-frame className'); // TODO: use const 483 } 484 if (!contentWidthEl) { 485 throw new Error('needs fc-scrollgrid-shrink-cushion className'); 486 } 487 return cellEl.getBoundingClientRect().width - allWidthEl.getBoundingClientRect().width + // the cell padding+border 488 contentWidthEl.getBoundingClientRect().width; 489 } 490 491 var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; 492 // Adding 493 function addWeeks(m, n) { 494 var a = dateToUtcArray(m); 495 a[2] += n * 7; 496 return arrayToUtcDate(a); 497 } 498 function addDays(m, n) { 499 var a = dateToUtcArray(m); 500 a[2] += n; 501 return arrayToUtcDate(a); 502 } 503 function addMs(m, n) { 504 var a = dateToUtcArray(m); 505 a[6] += n; 506 return arrayToUtcDate(a); 507 } 508 // Diffing (all return floats) 509 // TODO: why not use ranges? 510 function diffWeeks(m0, m1) { 511 return diffDays(m0, m1) / 7; 512 } 513 function diffDays(m0, m1) { 514 return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24); 515 } 516 function diffHours(m0, m1) { 517 return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60); 518 } 519 function diffMinutes(m0, m1) { 520 return (m1.valueOf() - m0.valueOf()) / (1000 * 60); 521 } 522 function diffSeconds(m0, m1) { 523 return (m1.valueOf() - m0.valueOf()) / 1000; 524 } 525 function diffDayAndTime(m0, m1) { 526 var m0day = startOfDay(m0); 527 var m1day = startOfDay(m1); 528 return { 529 years: 0, 530 months: 0, 531 days: Math.round(diffDays(m0day, m1day)), 532 milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf()), 533 }; 534 } 535 // Diffing Whole Units 536 function diffWholeWeeks(m0, m1) { 537 var d = diffWholeDays(m0, m1); 538 if (d !== null && d % 7 === 0) { 539 return d / 7; 540 } 541 return null; 542 } 543 function diffWholeDays(m0, m1) { 544 if (timeAsMs(m0) === timeAsMs(m1)) { 545 return Math.round(diffDays(m0, m1)); 546 } 547 return null; 548 } 549 // Start-Of 550 function startOfDay(m) { 551 return arrayToUtcDate([ 552 m.getUTCFullYear(), 553 m.getUTCMonth(), 554 m.getUTCDate(), 555 ]); 556 } 557 function startOfHour(m) { 558 return arrayToUtcDate([ 559 m.getUTCFullYear(), 560 m.getUTCMonth(), 561 m.getUTCDate(), 562 m.getUTCHours(), 563 ]); 564 } 565 function startOfMinute(m) { 566 return arrayToUtcDate([ 567 m.getUTCFullYear(), 568 m.getUTCMonth(), 569 m.getUTCDate(), 570 m.getUTCHours(), 571 m.getUTCMinutes(), 572 ]); 573 } 574 function startOfSecond(m) { 575 return arrayToUtcDate([ 576 m.getUTCFullYear(), 577 m.getUTCMonth(), 578 m.getUTCDate(), 579 m.getUTCHours(), 580 m.getUTCMinutes(), 581 m.getUTCSeconds(), 582 ]); 583 } 584 // Week Computation 585 function weekOfYear(marker, dow, doy) { 586 var y = marker.getUTCFullYear(); 587 var w = weekOfGivenYear(marker, y, dow, doy); 588 if (w < 1) { 589 return weekOfGivenYear(marker, y - 1, dow, doy); 590 } 591 var nextW = weekOfGivenYear(marker, y + 1, dow, doy); 592 if (nextW >= 1) { 593 return Math.min(w, nextW); 594 } 595 return w; 596 } 597 function weekOfGivenYear(marker, year, dow, doy) { 598 var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]); 599 var dayStart = startOfDay(marker); 600 var days = Math.round(diffDays(firstWeekStart, dayStart)); 601 return Math.floor(days / 7) + 1; // zero-indexed 602 } 603 // start-of-first-week - start-of-year 604 function firstWeekOffset(year, dow, doy) { 605 // first-week day -- which january is always in the first week (4 for iso, 1 for other) 606 var fwd = 7 + dow - doy; 607 // first-week day local weekday -- which local weekday is fwd 608 var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7; 609 return -fwdlw + fwd - 1; 610 } 611 // Array Conversion 612 function dateToLocalArray(date) { 613 return [ 614 date.getFullYear(), 615 date.getMonth(), 616 date.getDate(), 617 date.getHours(), 618 date.getMinutes(), 619 date.getSeconds(), 620 date.getMilliseconds(), 621 ]; 622 } 623 function arrayToLocalDate(a) { 624 return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month 625 a[3] || 0, a[4] || 0, a[5] || 0); 626 } 627 function dateToUtcArray(date) { 628 return [ 629 date.getUTCFullYear(), 630 date.getUTCMonth(), 631 date.getUTCDate(), 632 date.getUTCHours(), 633 date.getUTCMinutes(), 634 date.getUTCSeconds(), 635 date.getUTCMilliseconds(), 636 ]; 637 } 638 function arrayToUtcDate(a) { 639 // according to web standards (and Safari), a month index is required. 640 // massage if only given a year. 641 if (a.length === 1) { 642 a = a.concat([0]); 643 } 644 return new Date(Date.UTC.apply(Date, a)); 645 } 646 // Other Utils 647 function isValidDate(m) { 648 return !isNaN(m.valueOf()); 649 } 650 function timeAsMs(m) { 651 return m.getUTCHours() * 1000 * 60 * 60 + 652 m.getUTCMinutes() * 1000 * 60 + 653 m.getUTCSeconds() * 1000 + 654 m.getUTCMilliseconds(); 655 } 656 657 function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) { 658 return { 659 instanceId: guid(), 660 defId: defId, 661 range: range, 662 forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo, 663 forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo, 664 }; 665 } 666 667 var hasOwnProperty = Object.prototype.hasOwnProperty; 668 // Merges an array of objects into a single object. 669 // The second argument allows for an array of property names who's object values will be merged together. 670 function mergeProps(propObjs, complexPropsMap) { 671 var dest = {}; 672 if (complexPropsMap) { 673 for (var name_1 in complexPropsMap) { 674 var complexObjs = []; 675 // collect the trailing object values, stopping when a non-object is discovered 676 for (var i = propObjs.length - 1; i >= 0; i -= 1) { 677 var val = propObjs[i][name_1]; 678 if (typeof val === 'object' && val) { // non-null object 679 complexObjs.unshift(val); 680 } 681 else if (val !== undefined) { 682 dest[name_1] = val; // if there were no objects, this value will be used 683 break; 684 } 685 } 686 // if the trailing values were objects, use the merged value 687 if (complexObjs.length) { 688 dest[name_1] = mergeProps(complexObjs); 689 } 690 } 691 } 692 // copy values into the destination, going from last to first 693 for (var i = propObjs.length - 1; i >= 0; i -= 1) { 694 var props = propObjs[i]; 695 for (var name_2 in props) { 696 if (!(name_2 in dest)) { // if already assigned by previous props or complex props, don't reassign 697 dest[name_2] = props[name_2]; 698 } 699 } 700 } 701 return dest; 702 } 703 function filterHash(hash, func) { 704 var filtered = {}; 705 for (var key in hash) { 706 if (func(hash[key], key)) { 707 filtered[key] = hash[key]; 708 } 709 } 710 return filtered; 711 } 712 function mapHash(hash, func) { 713 var newHash = {}; 714 for (var key in hash) { 715 newHash[key] = func(hash[key], key); 716 } 717 return newHash; 718 } 719 function arrayToHash(a) { 720 var hash = {}; 721 for (var _i = 0, a_1 = a; _i < a_1.length; _i++) { 722 var item = a_1[_i]; 723 hash[item] = true; 724 } 725 return hash; 726 } 727 function buildHashFromArray(a, func) { 728 var hash = {}; 729 for (var i = 0; i < a.length; i += 1) { 730 var tuple = func(a[i], i); 731 hash[tuple[0]] = tuple[1]; 732 } 733 return hash; 734 } 735 function hashValuesToArray(obj) { 736 var a = []; 737 for (var key in obj) { 738 a.push(obj[key]); 739 } 740 return a; 741 } 742 function isPropsEqual(obj0, obj1) { 743 if (obj0 === obj1) { 744 return true; 745 } 746 for (var key in obj0) { 747 if (hasOwnProperty.call(obj0, key)) { 748 if (!(key in obj1)) { 749 return false;
750 } 751 } 752 } 753 for (var key in obj1) { 754 if (hasOwnProperty.call(obj1, key)) { 755 if (obj0[key] !== obj1[key]) { 756 return false; 757 } 758 } 759 } 760 return true; 761 } 762 function getUnequalProps(obj0, obj1) { 763 var keys = []; 764 for (var key in obj0) { 765 if (hasOwnProperty.call(obj0, key)) { 766 if (!(key in obj1)) { 767 keys.push(key); 768 } 769 } 770 } 771 for (var key in obj1) { 772 if (hasOwnProperty.call(obj1, key)) { 773 if (obj0[key] !== obj1[key]) { 774 keys.push(key); 775 } 776 } 777 } 778 return keys; 779 } 780 function compareObjs(oldProps, newProps, equalityFuncs) { 781 if (equalityFuncs === void 0) { equalityFuncs = {}; } 782 if (oldProps === newProps) { 783 return true; 784 } 785 for (var key in newProps) { 786 if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) ; 787 else { 788 return false; 789 } 790 } 791 // check for props that were omitted in the new 792 for (var key in oldProps) { 793 if (!(key in newProps)) { 794 return false; 795 } 796 } 797 return true; 798 } 799 /* 800 assumed "true" equality for handler names like "onReceiveSomething" 801 */ 802 function isObjValsEqual(val0, val1, comparator) { 803 if (val0 === val1 || comparator === true) { 804 return true; 805 } 806 if (comparator) { 807 return comparator(val0, val1); 808 } 809 return false; 810 } 811 function collectFromHash(hash, startIndex, endIndex, step) { 812 if (startIndex === void 0) { startIndex = 0; } 813 if (step === void 0) { step = 1; } 814 var res = []; 815 if (endIndex == null) { 816 endIndex = Object.keys(hash).length; 817 } 818 for (var i = startIndex; i < endIndex; i += step) { 819 var val = hash[i]; 820 if (val !== undefined) { // will disregard undefined for sparse arrays 821 res.push(val); 822 } 823 } 824 return res; 825 } 826 827 function parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) { 828 for (var i = 0; i < recurringTypes.length; i += 1) { 829 var parsed = recurringTypes[i].parse(refined, dateEnv); 830 if (parsed) { 831 var allDay = refined.allDay; 832 if (allDay == null) { 833 allDay = defaultAllDay; 834 if (allDay == null) { 835 allDay = parsed.allDayGuess; 836 if (allDay == null) { 837 allDay = false; 838 } 839 } 840 } 841 return { 842 allDay: allDay, 843 duration: parsed.duration, 844 typeData: parsed.typeData, 845 typeId: i, 846 }; 847 } 848 } 849 return null; 850 } 851 function expandRecurring(eventStore, framingRange, context) { 852 var dateEnv = context.dateEnv, pluginHooks = context.pluginHooks, options = context.options; 853 var defs = eventStore.defs, instances = eventStore.instances; 854 // remove existing recurring instances 855 // TODO: bad. always expand events as a second step 856 instances = filterHash(instances, function (instance) { return !defs[instance.defId].recurringDef; }); 857 for (var defId in defs) { 858 var def = defs[defId]; 859 if (def.recurringDef) { 860 var duration = def.recurringDef.duration; 861 if (!duration) { 862 duration = def.allDay ? 863 options.defaultAllDayEventDuration : 864 options.defaultTimedEventDuration; 865 } 866 var starts = expandRecurringRanges(def, duration, framingRange, dateEnv, pluginHooks.recurringTypes); 867 for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) { 868 var start = starts_1[_i]; 869 var instance = createEventInstance(defId, { 870 start: start, 871 end: dateEnv.add(start, duration), 872 }); 873 instances[instance.instanceId] = instance; 874 } 875 } 876 } 877 return { defs: defs, instances: instances }; 878 } 879 /* 880 Event MUST have a recurringDef 881 */ 882 function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) { 883 var typeDef = recurringTypes[eventDef.recurringDef.typeId]; 884 var markers = typeDef.expand(eventDef.recurringDef.typeData, { 885 start: dateEnv.subtract(framingRange.start, duration), 886 end: framingRange.end, 887 }, dateEnv); 888 // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to 889 if (eventDef.allDay) { 890 markers = markers.map(startOfDay); 891 } 892 return markers; 893 } 894 895 var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
vendor: 7,706 bytes, lines 896-1121
896 var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/; 897 // Parsing and Creation 898 function createDuration(input, unit) { 899 var _a; 900 if (typeof input === 'string') { 901 return parseString(input); 902 } 903 if (typeof input === 'object' && input) { // non-null object 904 return parseObject(input); 905 } 906 if (typeof input === 'number') { 907 return parseObject((_a = {}, _a[unit || 'milliseconds'] = input, _a)); 908 } 909 return null; 910 } 911 function parseString(s) { 912 var m = PARSE_RE.exec(s); 913 if (m) { 914 var sign = m[1] ? -1 : 1; 915 return { 916 years: 0, 917 months: 0, 918 days: sign * (m[2] ? parseInt(m[2], 10) : 0), 919 milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours 920 (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes 921 (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds 922 (m[6] ? parseInt(m[6], 10) : 0) // ms 923 ), 924 }; 925 } 926 return null; 927 } 928 function parseObject(obj) { 929 var duration = { 930 years: obj.years || obj.year || 0, 931 months: obj.months || obj.month || 0, 932 days: obj.days || obj.day || 0, 933 milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours 934 (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes 935 (obj.seconds || obj.second || 0) * 1000 + // seconds 936 (obj.milliseconds || obj.millisecond || obj.ms || 0), // ms 937 }; 938 var weeks = obj.weeks || obj.week; 939 if (weeks) { 940 duration.days += weeks * 7; 941 duration.specifiedWeeks = true; 942 } 943 return duration; 944 } 945 // Equality 946 function durationsEqual(d0, d1) { 947 return d0.years === d1.years && 948 d0.months === d1.months && 949 d0.days === d1.days && 950 d0.milliseconds === d1.milliseconds; 951 } 952 function asCleanDays(dur) { 953 if (!dur.years && !dur.months && !dur.milliseconds) { 954 return dur.days; 955 } 956 return 0; 957 } 958 // Simple Math 959 function addDurations(d0, d1) { 960 return { 961 years: d0.years + d1.years, 962 months: d0.months + d1.months, 963 days: d0.days + d1.days, 964 milliseconds: d0.milliseconds + d1.milliseconds, 965 }; 966 } 967 function subtractDurations(d1, d0) { 968 return { 969 years: d1.years - d0.years, 970 months: d1.months - d0.months, 971 days: d1.days - d0.days, 972 milliseconds: d1.milliseconds - d0.milliseconds, 973 }; 974 } 975 function multiplyDuration(d, n) { 976 return { 977 years: d.years * n, 978 months: d.months * n, 979 days: d.days * n, 980 milliseconds: d.milliseconds * n, 981 }; 982 } 983 // Conversions 984 // "Rough" because they are based on average-case Gregorian months/years 985 function asRoughYears(dur) { 986 return asRoughDays(dur) / 365; 987 } 988 function asRoughMonths(dur) { 989 return asRoughDays(dur) / 30; 990 } 991 function asRoughDays(dur) { 992 return asRoughMs(dur) / 864e5; 993 } 994 function asRoughMinutes(dur) { 995 return asRoughMs(dur) / (1000 * 60); 996 } 997 function asRoughSeconds(dur) { 998 return asRoughMs(dur) / 1000; 999 } 1000 function asRoughMs(dur) { 1001 return dur.years * (365 * 864e5) + 1002 dur.months * (30 * 864e5) + 1003 dur.days * 864e5 + 1004 dur.milliseconds; 1005 } 1006 // Advanced Math 1007 function wholeDivideDurations(numerator, denominator) { 1008 var res = null; 1009 for (var i = 0; i < INTERNAL_UNITS.length; i += 1) { 1010 var unit = INTERNAL_UNITS[i]; 1011 if (denominator[unit]) { 1012 var localRes = numerator[unit] / denominator[unit]; 1013 if (!isInt(localRes) || (res !== null && res !== localRes)) { 1014 return null; 1015 } 1016 res = localRes; 1017 } 1018 else if (numerator[unit]) { 1019 // needs to divide by something but can't! 1020 return null; 1021 } 1022 } 1023 return res; 1024 } 1025 function greatestDurationDenominator(dur) { 1026 var ms = dur.milliseconds; 1027 if (ms) { 1028 if (ms % 1000 !== 0) { 1029 return { unit: 'millisecond', value: ms }; 1030 } 1031 if (ms % (1000 * 60) !== 0) { 1032 return { unit: 'second', value: ms / 1000 }; 1033 } 1034 if (ms % (1000 * 60 * 60) !== 0) { 1035 return { unit: 'minute', value: ms / (1000 * 60) }; 1036 } 1037 if (ms) { 1038 return { unit: 'hour', value: ms / (1000 * 60 * 60) }; 1039 } 1040 } 1041 if (dur.days) { 1042 if (dur.specifiedWeeks && dur.days % 7 === 0) { 1043 return { unit: 'week', value: dur.days / 7 }; 1044 } 1045 return { unit: 'day', value: dur.days }; 1046 } 1047 if (dur.months) { 1048 return { unit: 'month', value: dur.months }; 1049 } 1050 if (dur.years) { 1051 return { unit: 'year', value: dur.years }; 1052 } 1053 return { unit: 'millisecond', value: 0 }; 1054 } 1055 1056 // timeZoneOffset is in minutes 1057 function buildIsoString(marker, timeZoneOffset, stripZeroTime) { 1058 if (stripZeroTime === void 0) { stripZeroTime = false; } 1059 var s = marker.toISOString(); 1060 s = s.replace('.000', ''); 1061 if (stripZeroTime) { 1062 s = s.replace('T00:00:00Z', ''); 1063 } 1064 if (s.length > 10) { // time part wasn't stripped, can add timezone info 1065 if (timeZoneOffset == null) { 1066 s = s.replace('Z', ''); 1067 } 1068 else if (timeZoneOffset !== 0) { 1069 s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true)); 1070 } 1071 // otherwise, its UTC-0 and we want to keep the Z 1072 } 1073 return s; 1074 } 1075 // formats the date, but with no time part 1076 // TODO: somehow merge with buildIsoString and stripZeroTime 1077 // TODO: rename. omit "string" 1078 function formatDayString(marker) { 1079 return marker.toISOString().replace(/T.*$/, ''); 1080 } 1081 // TODO: use Date::toISOString and use everything after the T? 1082 function formatIsoTimeString(marker) { 1083 return padStart(marker.getUTCHours(), 2) + ':' + 1084 padStart(marker.getUTCMinutes(), 2) + ':' + 1085 padStart(marker.getUTCSeconds(), 2); 1086 } 1087 function formatTimeZoneOffset(minutes, doIso) { 1088 if (doIso === void 0) { doIso = false; } 1089 var sign = minutes < 0 ? '-' : '+'; 1090 var abs = Math.abs(minutes); 1091 var hours = Math.floor(abs / 60); 1092 var mins = Math.round(abs % 60); 1093 if (doIso) { 1094 return sign + padStart(hours, 2) + ":" + padStart(mins, 2); 1095 } 1096 return "GMT" + sign + hours + (mins ? ":" + padStart(mins, 2) : ''); 1097 } 1098 1099 // TODO: new util arrayify? 1100 function removeExact(array, exactVal) { 1101 var removeCnt = 0; 1102 var i = 0; 1103 while (i < array.length) { 1104 if (array[i] === exactVal) { 1105 array.splice(i, 1); 1106 removeCnt += 1; 1107 } 1108 else { 1109 i += 1; 1110 } 1111 } 1112 return removeCnt; 1113 } 1114 function isArraysEqual(a0, a1, equalityFunc) { 1115 if (a0 === a1) { 1116 return true; 1117 } 1118 var len = a0.length; 1119 var i; 1120 if (len !== a1.length) { // not array? or not same length? 1121 return false;
1122 } 1123 for (i = 0; i < len; i += 1) { 1124 if (!(equalityFunc ? equalityFunc(a0[i], a1[i]) : a0[i] === a1[i])) { 1125 return false; 1126 } 1127 } 1128 return true; 1129 } 1130 1131 function memoize(workerFunc, resEquality, teardownFunc) { 1132 var currentArgs; 1133 var currentRes; 1134 return function () { 1135 var newArgs = []; 1136 for (var _i = 0; _i < arguments.length; _i++) { 1137 newArgs[_i] = arguments[_i]; 1138 } 1139 if (!currentArgs) { 1140 currentRes = workerFunc.apply(this, newArgs); 1141 } 1142 else if (!isArraysEqual(currentArgs, newArgs)) { 1143 if (teardownFunc) { 1144 teardownFunc(currentRes); 1145 } 1146 var res = workerFunc.apply(this, newArgs); 1147 if (!resEquality || !resEquality(res, currentRes)) { 1148 currentRes = res; 1149 } 1150 } 1151 currentArgs = newArgs; 1152 return currentRes; 1153 }; 1154 } 1155 function memoizeObjArg(workerFunc, resEquality, teardownFunc) { 1156 var _this = this; 1157 var currentArg; 1158 var currentRes; 1159 return function (newArg) { 1160 if (!currentArg) { 1161 currentRes = workerFunc.call(_this, newArg); 1162 } 1163 else if (!isPropsEqual(currentArg, newArg)) { 1164 if (teardownFunc) { 1165 teardownFunc(currentRes); 1166 } 1167 var res = workerFunc.call(_this, newArg); 1168 if (!resEquality || !resEquality(res, currentRes)) { 1169 currentRes = res; 1170 } 1171 } 1172 currentArg = newArg; 1173 return currentRes; 1174 }; 1175 } 1176 function memoizeArraylike(// used at all? 1177 workerFunc, resEquality, teardownFunc) { 1178 var _this = this; 1179 var currentArgSets = []; 1180 var currentResults = []; 1181 return function (newArgSets) { 1182 var currentLen = currentArgSets.length; 1183 var newLen = newArgSets.length; 1184 var i = 0; 1185 for (; i < currentLen; i += 1) { 1186 if (!newArgSets[i]) { // one of the old sets no longer exists 1187 if (teardownFunc) { 1188 teardownFunc(currentResults[i]); 1189 } 1190 } 1191 else if (!isArraysEqual(currentArgSets[i], newArgSets[i])) { 1192 if (teardownFunc) { 1193 teardownFunc(currentResults[i]); 1194 } 1195 var res = workerFunc.apply(_this, newArgSets[i]); 1196 if (!resEquality || !resEquality(res, currentResults[i])) { 1197 currentResults[i] = res; 1198 } 1199 } 1200 } 1201 for (; i < newLen; i += 1) { 1202 currentResults[i] = workerFunc.apply(_this, newArgSets[i]); 1203 } 1204 currentArgSets = newArgSets; 1205 currentResults.splice(newLen); // remove excess 1206 return currentResults; 1207 }; 1208 } 1209 function memoizeHashlike(// used? 1210 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: isBoolComplexEqual, 1845 footerToolbar: isBoolComplexEqual, 1846 buttonText: isBoolComplexEqual, 1847 buttonHints: isBoolComplexEqual, 1848 buttonIcons: isBoolComplexEqual, 1849 }; 1850 function isBoolComplexEqual(a, b) { 1851 if (typeof a === 'object' && typeof b === 'object' && a && b) { // both non-null objects 1852 return isPropsEqual(a, b); 1853 } 1854 return a === b; 1855 } 1856 // view-specific options 1857 // --------------------- 1858 var VIEW_OPTION_REFINERS = { 1859 type: String, 1860 component: identity, 1861 buttonText: String, 1862 buttonTextKey: String, 1863 dateProfileGeneratorClass: identity, 1864 usesMinMaxTime: Boolean, 1865 classNames: identity, 1866 content: identity, 1867 didMount: identity, 1868 willUnmount: identity, 1869 }; 1870 // util funcs 1871 // ---------------------------------------------------------------------------------------------------- 1872 function mergeRawOptions(optionSets) { 1873 return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS); 1874 } 1875 function refineProps(input, refiners) { 1876 var refined = {}; 1877 var extra = {}; 1878 for (var propName in refiners) { 1879 if (propName in input) { 1880 refined[propName] = refiners[propName](input[propName]); 1881 } 1882 } 1883 for (var propName in input) { 1884 if (!(propName in refiners)) { 1885 extra[propName] = input[propName]; 1886 } 1887 } 1888 return { refined: refined, extra: extra }; 1889 } 1890 function identity(raw) { 1891 return raw; 1892 } 1893 1894 function parseEvents(rawEvents, eventSource, context, allowOpenRange) { 1895 var eventStore = createEmptyEventStore(); 1896 var eventRefiners = buildEventRefiners(context); 1897 for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) { 1898 var rawEvent = rawEvents_1[_i]; 1899 var tuple = parseEvent(rawEvent, eventSource, context, allowOpenRange, eventRefiners); 1900 if (tuple) { 1901 eventTupleToStore(tuple, eventStore); 1902 } 1903 } 1904 return eventStore; 1905 } 1906 function eventTupleToStore(tuple, eventStore) { 1907 if (eventStore === void 0) { eventStore = createEmptyEventStore(); } 1908 eventStore.defs[tuple.def.defId] = tuple.def; 1909 if (tuple.instance) { 1910 eventStore.instances[tuple.instance.instanceId] = tuple.instance; 1911 } 1912 return eventStore; 1913 } 1914 // retrieves events that have the same groupId as the instance specified by `instanceId` 1915 // or they are the same as the instance. 1916 // why might instanceId not be in the store? an event from another calendar? 1917 function getRelevantEvents(eventStore, instanceId) { 1918 var instance = eventStore.instances[instanceId]; 1919 if (instance) { 1920 var def_1 = eventStore.defs[instance.defId]; 1921 // get events/instances with same group 1922 var newStore = filterEventStoreDefs(eventStore, function (lookDef) { return isEventDefsGrouped(def_1, lookDef); }); 1923 // add the original 1924 // TODO: wish we could use eventTupleToStore or something like it 1925 newStore.defs[def_1.defId] = def_1; 1926 newStore.instances[instance.instanceId] = instance; 1927 return newStore; 1928 } 1929 return createEmptyEventStore(); 1930 } 1931 function isEventDefsGrouped(def0, def1) { 1932 return Boolean(def0.groupId && def0.groupId === def1.groupId); 1933 } 1934 function createEmptyEventStore() { 1935 return { defs: {}, instances: {} }; 1936 } 1937 function mergeEventStores(store0, store1) { 1938 return { 1939 defs: __assign(__assign({}, store0.defs), store1.defs), 1940 instances: __assign(__assign({}, store0.instances), store1.instances), 1941 }; 1942 } 1943 function filterEventStoreDefs(eventStore, filterFunc) { 1944 var defs = filterHash(eventStore.defs, filterFunc); 1945 var instances = filterHash(eventStore.instances, function (instance) { return (defs[instance.defId] // still exists? 1946 ); }); 1947 return { defs: defs, instances: instances }; 1948 } 1949 function excludeSubEventStore(master, sub) { 1950 var defs = master.defs, instances = master.instances; 1951 var filteredDefs = {}; 1952 var filteredInstances = {}; 1953 for (var defId in defs) { 1954 if (!sub.defs[defId]) { // not explicitly excluded
vendor: 4,652 bytes, lines 1955-2074
1955 filteredDefs[defId] = defs[defId]; 1956 } 1957 } 1958 for (var instanceId in instances) { 1959 if (!sub.instances[instanceId] && // not explicitly excluded 1960 filteredDefs[instances[instanceId].defId] // def wasn't filtered away 1961 ) { 1962 filteredInstances[instanceId] = instances[instanceId]; 1963 } 1964 } 1965 return { 1966 defs: filteredDefs, 1967 instances: filteredInstances, 1968 }; 1969 } 1970 1971 function normalizeConstraint(input, context) { 1972 if (Array.isArray(input)) { 1973 return parseEvents(input, null, context, true); // allowOpenRange=true 1974 } 1975 if (typeof input === 'object' && input) { // non-null object 1976 return parseEvents([input], null, context, true); // allowOpenRange=true 1977 } 1978 if (input != null) { 1979 return String(input); 1980 } 1981 return null; 1982 } 1983 1984 function parseClassNames(raw) { 1985 if (Array.isArray(raw)) { 1986 return raw; 1987 } 1988 if (typeof raw === 'string') { 1989 return raw.split(/\s+/); 1990 } 1991 return []; 1992 } 1993 1994 // TODO: better called "EventSettings" or "EventConfig" 1995 // TODO: move this file into structs 1996 // TODO: separate constraint/overlap/allow, because selection uses only that, not other props 1997 var EVENT_UI_REFINERS = { 1998 display: String, 1999 editable: Boolean, 2000 startEditable: Boolean, 2001 durationEditable: Boolean, 2002 constraint: identity, 2003 overlap: identity, 2004 allow: identity, 2005 className: parseClassNames, 2006 classNames: parseClassNames, 2007 color: String, 2008 backgroundColor: String, 2009 borderColor: String, 2010 textColor: String, 2011 }; 2012 var EMPTY_EVENT_UI = { 2013 display: null, 2014 startEditable: null, 2015 durationEditable: null, 2016 constraints: [], 2017 overlap: null, 2018 allows: [], 2019 backgroundColor: '', 2020 borderColor: '', 2021 textColor: '', 2022 classNames: [], 2023 }; 2024 function createEventUi(refined, context) { 2025 var constraint = normalizeConstraint(refined.constraint, context); 2026 return { 2027 display: refined.display || null, 2028 startEditable: refined.startEditable != null ? refined.startEditable : refined.editable, 2029 durationEditable: refined.durationEditable != null ? refined.durationEditable : refined.editable, 2030 constraints: constraint != null ? [constraint] : [], 2031 overlap: refined.overlap != null ? refined.overlap : null, 2032 allows: refined.allow != null ? [refined.allow] : [], 2033 backgroundColor: refined.backgroundColor || refined.color || '', 2034 borderColor: refined.borderColor || refined.color || '', 2035 textColor: refined.textColor || '', 2036 classNames: (refined.className || []).concat(refined.classNames || []), // join singular and plural 2037 }; 2038 } 2039 // TODO: prevent against problems with <2 args! 2040 function combineEventUis(uis) { 2041 return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI); 2042 } 2043 function combineTwoEventUis(item0, item1) { 2044 return { 2045 display: item1.display != null ? item1.display : item0.display, 2046 startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable, 2047 durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable, 2048 constraints: item0.constraints.concat(item1.constraints), 2049 overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap, 2050 allows: item0.allows.concat(item1.allows), 2051 backgroundColor: item1.backgroundColor || item0.backgroundColor, 2052 borderColor: item1.borderColor || item0.borderColor, 2053 textColor: item1.textColor || item0.textColor, 2054 classNames: item0.classNames.concat(item1.classNames), 2055 }; 2056 } 2057 2058 var EVENT_NON_DATE_REFINERS = { 2059 id: String, 2060 groupId: String, 2061 title: String, 2062 url: String, 2063 interactive: Boolean, 2064 }; 2065 var EVENT_DATE_REFINERS = { 2066 start: identity, 2067 end: identity, 2068 date: identity, 2069 allDay: Boolean, 2070 }; 2071 var EVENT_REFINERS = __assign(__assign(__assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), { extendedProps: identity }); 2072 function parseEvent(raw, eventSource, context, allowOpenRange, refiners) { 2073 if (refiners === void 0) { refiners = buildEventRefiners(context); } 2074 var _a = refineEventDef(raw, context, refiners), refined
2074= _a.refined, extra = _a.extra; 2075 var defaultAllDay = computeIsDefaultAllDay(eventSource, context); 2076 var recurringRes = parseRecurring(refined, defaultAllDay, context.dateEnv, context.pluginHooks.recurringTypes); 2077 if (recurringRes) { 2078 var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', recurringRes.allDay, Boolean(recurringRes.duration), context); 2079 def.recurringDef = { 2080 typeId: recurringRes.typeId, 2081 typeData: recurringRes.typeData, 2082 duration: recurringRes.duration, 2083 }; 2084 return { def: def, instance: null }; 2085 } 2086 var singleRes = parseSingle(refined, defaultAllDay, context, allowOpenRange); 2087 if (singleRes) { 2088 var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', singleRes.allDay, singleRes.hasEnd, context); 2089 var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo); 2090 return { def: def, instance: instance }; 2091 } 2092 return null; 2093 } 2094 function refineEventDef(raw, context, refiners) { 2095 if (refiners === void 0) { refiners = buildEventRefiners(context); } 2096 return refineProps(raw, refiners); 2097 } 2098 function buildEventRefiners(context) { 2099 return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), context.pluginHooks.eventRefiners); 2100 } 2101 /* 2102 Will NOT populate extendedProps with the leftover properties. 2103 Will NOT populate date-related props. 2104 */ 2105 function parseEventDef(refined, extra, sourceId, allDay, hasEnd, context) { 2106 var def = { 2107 title: refined.title || '', 2108 groupId: refined.groupId || '', 2109 publicId: refined.id || '', 2110 url: refined.url || '', 2111 recurringDef: null, 2112 defId: guid(), 2113 sourceId: sourceId, 2114 allDay: allDay, 2115 hasEnd: hasEnd, 2116 interactive: refined.interactive, 2117 ui: createEventUi(refined, context), 2118 extendedProps: __assign(__assign({}, (refined.extendedProps || {})), extra), 2119 }; 2120 for (var _i = 0, _a = context.pluginHooks.eventDefMemberAdders; _i < _a.length; _i++) { 2121 var memberAdder = _a[_i]; 2122 __assign(def, memberAdder(refined)); 2123 } 2124 // help out EventApi from having user modify props 2125 Object.freeze(def.ui.classNames); 2126 Object.freeze(def.extendedProps); 2127 return def; 2128 } 2129 function parseSingle(refined, defaultAllDay, context, allowOpenRange) { 2130 var allDay = refined.allDay; 2131 var startMeta; 2132 var startMarker = null; 2133 var hasEnd = false; 2134 var endMeta; 2135 var endMarker = null; 2136 var startInput = refined.start != null ? refined.start : refined.date; 2137 startMeta = context.dateEnv.createMarkerMeta(startInput); 2138 if (startMeta) { 2139 startMarker = startMeta.marker; 2140 } 2141 else if (!allowOpenRange) { 2142 return null; 2143 } 2144 if (refined.end != null) { 2145 endMeta = context.dateEnv.createMarkerMeta(refined.end); 2146 } 2147 if (allDay == null) { 2148 if (defaultAllDay != null) { 2149 allDay = defaultAllDay; 2150 } 2151 else { 2152 // fall back to the date props LAST 2153 allDay = (!startMeta || startMeta.isTimeUnspecified) && 2154 (!endMeta || endMeta.isTimeUnspecified); 2155 } 2156 } 2157 if (allDay && startMarker) { 2158 startMarker = startOfDay(startMarker); 2159 } 2160 if (endMeta) { 2161 endMarker = endMeta.marker; 2162 if (allDay) { 2163 endMarker = startOfDay(endMarker); 2164 } 2165 if (startMarker && endMarker <= startMarker) { 2166 endMarker = null; 2167 } 2168 } 2169 if (endMarker) { 2170 hasEnd = true; 2171 } 2172 else if (!allowOpenRange) { 2173 hasEnd = context.options.forceEventDuration || false; 2174 endMarker = context.dateEnv.add(startMarker, allDay ? 2175 context.options.defaultAllDayEventDuration : 2176 context.options.defaultTimedEventDuration); 2177 } 2178 return { 2179 allDay: allDay, 2180 hasEnd: hasEnd, 2181 range: { start: startMarker, end: endMarker }, 2182 forcedStartTzo: startMeta ? startMeta.forcedTzo : null, 2183 forcedEndTzo: endMeta ? endMeta.forcedTzo : null, 2184 }; 2185 } 2186 function computeIsDefaultAllDay(eventSource, context) { 2187 var res = null; 2188 if (eventSource) { 2189 res = eventSource.defaultAllDay; 2190 } 2191 if (res == null) { 2192 res = context.options.defaultAllDay; 2193 } 2194 return res; 2195 } 2196 2197 /* Date stuff that doesn't belong in datelib core 2198 ----------------------------------------------------------------------------------------------------------------------*/ 2199 // given a timed range, computes an all-day range that has the same exact duration, 2200 // but whose start time is aligned with the start of the day. 2201 function computeAlignedDayRange(timedRange) { 2202 var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1; 2203 var start = startOfDay(timedRange.start); 2204 var end = addDays(start, dayCnt); 2205 return { start: start, end: end }; 2206 } 2207 // given a timed range, computes an all-day range based on how for the end date bleeds into the next day 2208 // TODO: give nextDayThreshold a default arg 2209 function computeVisibleDayRange(timedRange, nextDayThreshold) { 2210 if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); } 2211 var startDay = null; 2212 var endDay = null; 2213 if (timedRange.end) { 2214 endDay = startOfDay(timedRange.end); 2215 var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay` 2216 // If the end time is actually inclusively part of the next day and is equal to or
vendor: 16,384 bytes, lines 2217-2599
2217 // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`. 2218 // Otherwise, leaving it as inclusive will cause it to exclude `endDay`. 2219 if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) { 2220 endDay = addDays(endDay, 1); 2221 } 2222 } 2223 if (timedRange.start) { 2224 startDay = startOfDay(timedRange.start); // the beginning of the day the range starts 2225 // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day. 2226 if (endDay && endDay <= startDay) { 2227 endDay = addDays(startDay, 1); 2228 } 2229 } 2230 return { start: startDay, end: endDay }; 2231 } 2232 // spans from one day into another? 2233 function isMultiDayRange(range) { 2234 var visibleRange = computeVisibleDayRange(range); 2235 return diffDays(visibleRange.start, visibleRange.end) > 1; 2236 } 2237 function diffDates(date0, date1, dateEnv, largeUnit) { 2238 if (largeUnit === 'year') { 2239 return createDuration(dateEnv.diffWholeYears(date0, date1), 'year'); 2240 } 2241 if (largeUnit === 'month') { 2242 return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month'); 2243 } 2244 return diffDayAndTime(date0, date1); // returns a duration 2245 } 2246 2247 function parseRange(input, dateEnv) { 2248 var start = null; 2249 var end = null; 2250 if (input.start) { 2251 start = dateEnv.createMarker(input.start); 2252 } 2253 if (input.end) { 2254 end = dateEnv.createMarker(input.end); 2255 } 2256 if (!start && !end) { 2257 return null; 2258 } 2259 if (start && end && end < start) { 2260 return null; 2261 } 2262 return { start: start, end: end }; 2263 } 2264 // SIDE-EFFECT: will mutate ranges. 2265 // Will return a new array result. 2266 function invertRanges(ranges, constraintRange) { 2267 var invertedRanges = []; 2268 var start = constraintRange.start; // the end of the previous range. the start of the new range 2269 var i; 2270 var dateRange; 2271 // ranges need to be in order. required for our date-walking algorithm 2272 ranges.sort(compareRanges); 2273 for (i = 0; i < ranges.length; i += 1) { 2274 dateRange = ranges[i]; 2275 // add the span of time before the event (if there is any) 2276 if (dateRange.start > start) { // compare millisecond time (skip any ambig logic) 2277 invertedRanges.push({ start: start, end: dateRange.start }); 2278 } 2279 if (dateRange.end > start) { 2280 start = dateRange.end; 2281 } 2282 } 2283 // add the span of time after the last event (if there is any) 2284 if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic) 2285 invertedRanges.push({ start: start, end: constraintRange.end }); 2286 } 2287 return invertedRanges; 2288 } 2289 function compareRanges(range0, range1) { 2290 return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first 2291 } 2292 function intersectRanges(range0, range1) { 2293 var start = range0.start, end = range0.end; 2294 var newRange = null; 2295 if (range1.start !== null) { 2296 if (start === null) { 2297 start = range1.start; 2298 } 2299 else { 2300 start = new Date(Math.max(start.valueOf(), range1.start.valueOf())); 2301 } 2302 } 2303 if (range1.end != null) { 2304 if (end === null) { 2305 end = range1.end; 2306 } 2307 else { 2308 end = new Date(Math.min(end.valueOf(), range1.end.valueOf())); 2309 } 2310 } 2311 if (start === null || end === null || start < end) { 2312 newRange = { start: start, end: end }; 2313 } 2314 return newRange; 2315 } 2316 function rangesEqual(range0, range1) { 2317 return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) && 2318 (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf()); 2319 } 2320 function rangesIntersect(range0, range1) { 2321 return (range0.end === null || range1.start === null || range0.end > range1.start) && 2322 (range0.start === null || range1.end === null || range0.start < range1.end); 2323 } 2324 function rangeContainsRange(outerRange, innerRange) { 2325 return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) && 2326 (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end)); 2327 } 2328 function rangeContainsMarker(range, date) { 2329 return (range.start === null || date >= range.start) && 2330 (range.end === null || date < range.end); 2331 } 2332 // If the given date is not within the given range, move it inside. 2333 // (If it's past the end, make it one millisecond before the end). 2334 function constrainMarkerToRange(date, range) { 2335 if (range.start != null && date < range.start) { 2336 return range.start; 2337 } 2338 if (range.end != null && date >= range.end) { 2339 return new Date(range.end.valueOf() - 1); 2340 } 2341 return date; 2342 } 2343 2344 /* 2345 Specifying nextDayThreshold signals that all-day ranges should be sliced. 2346 */ 2347 function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) { 2348 var inverseBgByGroupId = {}; 2349 var inverseBgByDefId = {}; 2350 var defByGroupId = {}; 2351 var bgRanges = []; 2352 var fgRanges = []; 2353 var eventUis = compileEventUis(eventStore.defs, eventUiBases); 2354 for (var defId in eventStore.defs) { 2355 var def = eventStore.defs[defId]; 2356 var ui = eventUis[def.defId]; 2357 if (ui.display === 'inverse-background') { 2358 if (def.groupId) { 2359 inverseBgByGroupId[def.groupId] = []; 2360 if (!defByGroupId[def.groupId]) { 2361 defByGroupId[def.groupId] = def; 2362 } 2363 } 2364 else { 2365 inverseBgByDefId[defId] = []; 2366 } 2367 } 2368 } 2369 for (var instanceId in eventStore.instances) { 2370 var instance = eventStore.instances[instanceId]; 2371 var def = eventStore.defs[instance.defId]; 2372 var ui = eventUis[def.defId]; 2373 var origRange = instance.range; 2374 var normalRange = (!def.allDay && nextDayThreshold) ? 2375 computeVisibleDayRange(origRange, nextDayThreshold) : 2376 origRange; 2377 var slicedRange = intersectRanges(normalRange, framingRange); 2378 if (slicedRange) { 2379 if (ui.display === 'inverse-background') { 2380 if (def.groupId) { 2381 inverseBgByGroupId[def.groupId].push(slicedRange); 2382 } 2383 else { 2384 inverseBgByDefId[instance.defId].push(slicedRange); 2385 } 2386 } 2387 else if (ui.display !== 'none') { 2388 (ui.display === 'background' ? bgRanges : fgRanges).push({ 2389 def: def, 2390 ui: ui, 2391 instance: instance, 2392 range: slicedRange, 2393 isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(), 2394 isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf(), 2395 }); 2396 } 2397 } 2398 } 2399 for (var groupId in inverseBgByGroupId) { // BY GROUP 2400 var ranges = inverseBgByGroupId[groupId]; 2401 var invertedRanges = invertRanges(ranges, framingRange); 2402 for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) { 2403 var invertedRange = invertedRanges_1[_i]; 2404 var def = defByGroupId[groupId]; 2405 var ui = eventUis[def.defId]; 2406 bgRanges.push({ 2407 def: def, 2408 ui: ui, 2409 instance: null, 2410 range: invertedRange, 2411 isStart: false, 2412 isEnd: false, 2413 }); 2414 } 2415 } 2416 for (var defId in inverseBgByDefId) { 2417 var ranges = inverseBgByDefId[defId]; 2418 var invertedRanges = invertRanges(ranges, framingRange); 2419 for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) { 2420 var invertedRange = invertedRanges_2[_a]; 2421 bgRanges.push({ 2422 def: eventStore.defs[defId], 2423 ui: eventUis[defId], 2424 instance: null, 2425 range: invertedRange, 2426 isStart: false, 2427 isEnd: false, 2428 }); 2429 } 2430 } 2431 return { bg: bgRanges, fg: fgRanges }; 2432 } 2433 function hasBgRendering(def) { 2434 return def.ui.display === 'background' || def.ui.display === 'inverse-background'; 2435 } 2436 function setElSeg(el, seg) { 2437 el.fcSeg = seg; 2438 } 2439 function getElSeg(el) { 2440 return el.fcSeg || 2441 el.parentNode.fcSeg || // for the harness 2442 null; 2443 } 2444 // event ui computation 2445 function compileEventUis(eventDefs, eventUiBases) { 2446 return mapHash(eventDefs, function (eventDef) { return compileEventUi(eventDef, eventUiBases); }); 2447 } 2448 function compileEventUi(eventDef, eventUiBases) { 2449 var uis = []; 2450 if (eventUiBases['']) { 2451 uis.push(eventUiBases['']); 2452 } 2453 if (eventUiBases[eventDef.defId]) { 2454 uis.push(eventUiBases[eventDef.defId]); 2455 } 2456 uis.push(eventDef.ui); 2457 return combineEventUis(uis); 2458 } 2459 function sortEventSegs(segs, eventOrderSpecs) { 2460 var objs = segs.map(buildSegCompareObj); 2461 objs.sort(function (obj0, obj1) { return compareByFieldSpecs(obj0, obj1, eventOrderSpecs); }); 2462 return objs.map(function (c) { return c._seg; }); 2463 } 2464 // returns a object with all primitive props that can be compared 2465 function buildSegCompareObj(seg) { 2466 var eventRange = seg.eventRange; 2467 var eventDef = eventRange.def; 2468 var range = eventRange.instance ? eventRange.instance.range : eventRange.range; 2469 var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events 2470 var end = range.end ? range.end.valueOf() : 0; // " 2471 return __assign(__assign(__assign({}, eventDef.extendedProps), eventDef), { id: eventDef.publicId, start: start, 2472 end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg }); 2473 } 2474 function computeSegDraggable(seg, context) { 2475 var pluginHooks = context.pluginHooks; 2476 var transformers = pluginHooks.isDraggableTransformers; 2477 var _a = seg.eventRange, def = _a.def, ui = _a.ui; 2478 var val = ui.startEditable; 2479 for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) { 2480 var transformer = transformers_1[_i]; 2481 val = transformer(val, def, ui, context); 2482 } 2483 return val; 2484 } 2485 function computeSegStartResizable(seg, context) { 2486 return seg.isStart && seg.eventRange.ui.durationEditable && context.options.eventResizableFromStart; 2487 } 2488 function computeSegEndResizable(seg, context) { 2489 return seg.isEnd && seg.eventRange.ui.durationEditable; 2490 } 2491 function buildSegTimeText(seg, timeFormat, context, defaultDisplayEventTime, // defaults to true 2492 defaultDisplayEventEnd, // defaults to true 2493 startOverride, endOverride) { 2494 var dateEnv = context.dateEnv, options = context.options; 2495 var displayEventTime = options.displayEventTime, displayEventEnd = options.displayEventEnd; 2496 var eventDef = seg.eventRange.def; 2497 var eventInstance = seg.eventRange.instance; 2498 if (displayEventTime == null) { 2499 displayEventTime = defaultDisplayEventTime !== false; 2500 } 2501 if (displayEventEnd == null) { 2502 displayEventEnd = defaultDisplayEventEnd !== false; 2503 } 2504 var wholeEventStart = eventInstance.range.start; 2505 var wholeEventEnd = eventInstance.range.end; 2506 var segStart = startOverride || seg.start || seg.eventRange.range.start; 2507 var segEnd = endOverride || seg.end || seg.eventRange.range.end; 2508 var isStartDay = startOfDay(wholeEventStart).valueOf() === startOfDay(segStart).valueOf(); 2509 var isEndDay = startOfDay(addMs(wholeEventEnd, -1)).valueOf() === startOfDay(addMs(segEnd, -1)).valueOf(); 2510 if (displayEventTime && !eventDef.allDay && (isStartDay || isEndDay)) { 2511 segStart = isStartDay ? wholeEventStart : segStart; 2512 segEnd = isEndDay ? wholeEventEnd : segEnd; 2513 if (displayEventEnd && eventDef.hasEnd) { 2514 return dateEnv.formatRange(segStart, segEnd, timeFormat, { 2515 forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo, 2516 forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo, 2517 }); 2518 } 2519 return dateEnv.format(segStart, timeFormat, { 2520 forcedTzo: startOverride ? null : eventInstance.forcedStartTzo, // nooooo, same 2521 }); 2522 } 2523 return ''; 2524 } 2525 function getSegMeta(seg, todayRange, nowDate) { 2526 var segRange = seg.eventRange.range; 2527 return { 2528 isPast: segRange.end < (nowDate || todayRange.start), 2529 isFuture: segRange.start >= (nowDate || todayRange.end), 2530 isToday: todayRange && rangeContainsMarker(todayRange, segRange.start), 2531 }; 2532 } 2533 function getEventClassNames(props) { 2534 var classNames = ['fc-event']; 2535 if (props.isMirror) { 2536 classNames.push('fc-event-mirror'); 2537 } 2538 if (props.isDraggable) { 2539 classNames.push('fc-event-draggable'); 2540 } 2541 if (props.isStartResizable || props.isEndResizable) { 2542 classNames.push('fc-event-resizable'); 2543 } 2544 if (props.isDragging) { 2545 classNames.push('fc-event-dragging'); 2546 } 2547 if (props.isResizing) { 2548 classNames.push('fc-event-resizing'); 2549 } 2550 if (props.isSelected) { 2551 classNames.push('fc-event-selected'); 2552 } 2553 if (props.isStart) { 2554 classNames.push('fc-event-start'); 2555 } 2556 if (props.isEnd) { 2557 classNames.push('fc-event-end'); 2558 } 2559 if (props.isPast) { 2560 classNames.push('fc-event-past'); 2561 } 2562 if (props.isToday) { 2563 classNames.push('fc-event-today'); 2564 } 2565 if (props.isFuture) { 2566 classNames.push('fc-event-future'); 2567 } 2568 return classNames; 2569 } 2570 function buildEventRangeKey(eventRange) { 2571 return eventRange.instance 2572 ? eventRange.instance.instanceId 2573 : eventRange.def.defId + ":" + eventRange.range.start.toISOString(); 2574 // inverse-background events don't have specific instances. TODO: better solution 2575 } 2576 function getSegAnchorAttrs(seg, context) { 2577 var _a = seg.eventRange, def = _a.def, instance = _a.instance; 2578 var url = def.url; 2579 if (url) { 2580 return { href: url }; 2581 } 2582 var emitter = context.emitter, options = context.options; 2583 var eventInteractive = options.eventInteractive; 2584 if (eventInteractive == null) { 2585 eventInteractive = def.interactive; 2586 if (eventInteractive == null) { 2587 eventInteractive = Boolean(emitter.hasHandlers('eventClick')); 2588 } 2589 } 2590 // mock what happens in EventClicking 2591 if (eventInteractive) { 2592 // only attach keyboard-related handlers because click handler is already done in EventClicking 2593 return createAriaKeyboardAttrs(function (ev) { 2594 emitter.trigger('eventClick', { 2595 el: ev.target, 2596 event: new EventApi(context, def, instance), 2597 jsEvent: ev, 2598 view: context.viewApi, 2599
2599 }); 2600 }); 2601 } 2602 return {}; 2603 } 2604 2605 var STANDARD_PROPS = { 2606 start: identity, 2607 end: identity, 2608 allDay: Boolean, 2609 }; 2610 function parseDateSpan(raw, dateEnv, defaultDuration) { 2611 var span = parseOpenDateSpan(raw, dateEnv); 2612 var range = span.range; 2613 if (!range.start) { 2614 return null; 2615 } 2616 if (!range.end) { 2617 if (defaultDuration == null) { 2618 return null; 2619 } 2620 range.end = dateEnv.add(range.start, defaultDuration); 2621 } 2622 return span; 2623 } 2624 /* 2625 TODO: somehow combine with parseRange? 2626 Will return null if the start/end props were present but parsed invalidly. 2627 */ 2628 function parseOpenDateSpan(raw, dateEnv) { 2629 var _a = refineProps(raw, STANDARD_PROPS), standardProps = _a.refined, extra = _a.extra; 2630 var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null; 2631 var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null; 2632 var allDay = standardProps.allDay; 2633 if (allDay == null) { 2634 allDay = (startMeta && startMeta.isTimeUnspecified) && 2635 (!endMeta || endMeta.isTimeUnspecified); 2636 } 2637 return __assign({ range: { 2638 start: startMeta ? startMeta.marker : null, 2639 end: endMeta ? endMeta.marker : null, 2640 }, allDay: allDay }, extra); 2641 } 2642 function isDateSpansEqual(span0, span1) { 2643 return rangesEqual(span0.range, span1.range) && 2644 span0.allDay === span1.allDay && 2645 isSpanPropsEqual(span0, span1); 2646 } 2647 // the NON-DATE-RELATED props 2648 function isSpanPropsEqual(span0, span1) { 2649 for (var propName in span1) { 2650 if (propName !== 'range' && propName !== 'allDay') { 2651 if (span0[propName] !== span1[propName]) { 2652 return false; 2653 } 2654 } 2655 } 2656 // are there any props that span0 has that span1 DOESN'T have? 2657 // both have range/allDay, so no need to special-case. 2658 for (var propName in span0) { 2659 if (!(propName in span1)) { 2660 return false; 2661 } 2662 } 2663 return true; 2664 } 2665 function buildDateSpanApi(span, dateEnv) { 2666 return __assign(__assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), { allDay: span.allDay }); 2667 } 2668 function buildRangeApiWithTimeZone(range, dateEnv, omitTime) { 2669 return __assign(__assign({}, buildRangeApi(range, dateEnv, omitTime)), { timeZone: dateEnv.timeZone }); 2670 } 2671 function buildRangeApi(range, dateEnv, omitTime) { 2672 return { 2673 start: dateEnv.toDate(range.start), 2674 end: dateEnv.toDate(range.end), 2675 startStr: dateEnv.formatIso(range.start, { omitTime: omitTime }), 2676 endStr: dateEnv.formatIso(range.end, { omitTime: omitTime }), 2677 }; 2678 } 2679 function fabricateEventRange(dateSpan, eventUiBases, context) { 2680 var res = refineEventDef({ editable: false }, context); 2681 var def = parseEventDef(res.refined, res.extra, '', // sourceId 2682 dateSpan.allDay, true, // hasEnd 2683 context); 2684 return { 2685 def: def, 2686 ui: compileEventUi(def, eventUiBases), 2687 instance: createEventInstance(def.defId, dateSpan.range), 2688 range: dateSpan.range, 2689 isStart: true, 2690 isEnd: true, 2691 }; 2692 } 2693 2694 function triggerDateSelect(selection, pev, context) { 2695 context.emitter.trigger('select', __assign(__assign({}, buildDateSpanApiWithContext(selection, context)), { jsEvent: pev ? pev.origEvent : null, view: context.viewApi || context.calendarApi.view })); 2696 } 2697 function triggerDateUnselect(pev, context) { 2698 context.emitter.trigger('unselect', { 2699 jsEvent: pev ? pev.origEvent : null, 2700 view: context.viewApi || context.calendarApi.view, 2701 }); 2702 } 2703 function buildDateSpanApiWithContext(dateSpan, context) { 2704 var props = {}; 2705 for (var _i = 0, _a = context.pluginHooks.dateSpanTransforms; _i < _a.length; _i++) { 2706 var transform = _a[_i]; 2707 __assign(props, transform(dateSpan, context)); 2708 } 2709 __assign(props, buildDateSpanApi(dateSpan, context.dateEnv)); 2710 return props; 2711 } 2712 // Given an event's allDay status and start date, return what its fallback end date should be. 2713 // TODO: rename to computeDefaultEventEnd 2714 function getDefaultEventEnd(allDay, marker, context) { 2715 var dateEnv = context.dateEnv, options = context.options; 2716 var end = marker; 2717 if (allDay) { 2718 end = startOfDay(end); 2719 end = dateEnv.add(end, options.defaultAllDayEventDuration); 2720 } 2721 else { 2722 end = dateEnv.add(end, options.defaultTimedEventDuration); 2723 } 2724 return end; 2725 } 2726 2727 // applies the mutation to ALL defs/instances within the event store 2728 function applyMutationToEventStore(eventStore, eventConfigBase, mutation, context) { 2729 var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase); 2730 var dest = createEmptyEventStore(); 2731 for (var defId in eventStore.defs) { 2732 var def = eventStore.defs[defId]; 2733 dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, context); 2734 } 2735 for (var instanceId in eventStore.instances) { 2736 var instance = eventStore.instances[instanceId]; 2737 var def = dest.defs[instance.defId]; // important to grab the newly modified def 2738 dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, context); 2739 } 2740 return dest; 2741 } 2742 function applyMutationToEventDef(eventDef, eventConfig, mutation, context) { 2743 var standardProps = mutation.standardProps || {}; 2744 // if hasEnd has not been specified, guess a good value based on deltas. 2745 // if duration will change, there's no way the default duration will persist, 2746 // and thus, we need to mark the event as having a real end 2747 if (standardProps.hasEnd == null && 2748 eventConfig.durationEditable && 2749 (mutation.startDelta || mutation.endDelta)) { 2750 standardProps.hasEnd = true; // TODO: is this mutation okay? 2751 } 2752 var copy = __assign(__assign(__assign({}, eventDef), standardProps), { ui: __assign(__assign({}, eventDef.ui), standardProps.ui) }); 2753 if (mutation.extendedProps) { 2754 copy.extendedProps = __assign(__assign({}, copy.extendedProps), mutation.extendedProps); 2755 } 2756 for (var _i = 0, _a = context.pluginHooks.eventDefMutationAppliers; _i < _a.length; _i++) { 2757 var applier = _a[_i]; 2758 applier(copy, mutation, context); 2759 } 2760 if (!copy.hasEnd && context.options.forceEventDuration) { 2761 copy.hasEnd = true; 2762 } 2763 return copy; 2764 } 2765 function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef 2766 eventConfig, mutation, context) { 2767 var dateEnv = context.dateEnv; 2768 var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true; 2769 var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false; 2770 var copy = __assign({}, eventInstance); 2771 if (forceAllDay) { 2772 copy.range = computeAlignedDayRange(copy.range); 2773 } 2774 if (mutation.datesDelta && eventConfig.startEditable) { 2775 copy.range = { 2776 start: dateEnv.add(copy.range.start, mutation.datesDelta), 2777 end: dateEnv.add(copy.range.end, mutation.datesDelta), 2778 }; 2779 } 2780 if (mutation.startDelta && eventConfig.durationEditable) { 2781 copy.range = { 2782 start: dateEnv.add(copy.range.start, mutation.startDelta), 2783 end: copy.range.end, 2784 }; 2785 } 2786 if (mutation.endDelta && eventConfig.durationEditable) { 2787 copy.range = { 2788 start: copy.range.start, 2789 end: dateEnv.add(copy.range.end, mutation.endDelta), 2790 }; 2791 } 2792 if (clearEnd) { 2793 copy.range = { 2794 start: copy.range.start, 2795 end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context), 2796 }; 2797 } 2798 // in case event was all-day but the supplied deltas were not 2799 // better util for this? 2800 if (eventDef.allDay) { 2801 copy.range = { 2802 start: startOfDay(copy.range.start), 2803 end: startOfDay(copy.range.end), 2804 }; 2805 } 2806 // handle invalid durations 2807 if (copy.range.end < copy.range.start) { 2808 copy.range.end = getDefaultEventEnd(eventDef.allDay, copy.range.start, context); 2809 } 2810 return copy; 2811 } 2812 2813 // no public types yet. when there are, export from: 2814 // import {} from './api-type-deps' 2815 var ViewApi = /** @class */ (function () { 2816 function ViewApi(type, getCurrentData, dateEnv) { 2817 this.type = type; 2818 this.getCurrentData = getCurrentData; 2819 this.dateEnv = dateEnv; 2820 } 2821 Object.defineProperty(ViewApi.prototype, "calendar", { 2822 get: function () { 2823 return this.getCurrentData().calendarApi; 2824 }, 2825 enumerable: false, 2826 configurable: true 2827 }); 2828 Object.defineProperty(ViewApi.prototype, "title", { 2829 get: function () { 2830 return this.getCurrentData().viewTitle; 2831 }, 2832 enumerable: false, 2833 configurable: true 2834 }); 2835 Object.defineProperty(ViewApi.prototype, "activeStart", { 2836 get: function () { 2837 return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start); 2838 }, 2839 enumerable: false, 2840 configurable: true 2841 }); 2842 Object.defineProperty(ViewApi.prototype, "activeEnd", { 2843 get: function () { 2844 return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end); 2845 }, 2846 enumerable: false, 2847 configurable: true 2848 }); 2849 Object.defineProperty(ViewApi.prototype, "currentStart", { 2850 get: function () { 2851 return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start); 2852 }, 2853 enumerable: false, 2854 configurable: true 2855 }); 2856 Object.defineProperty(ViewApi.prototype, "currentEnd", { 2857 get: function () { 2858 return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end); 2859 }, 2860 enumerable: false, 2861 configurable: true 2862 }); 2863 ViewApi.prototype.getOption = function (name) { 2864 return this.getCurrentData().options[name]; // are the view-specific options 2865 }; 2866 return ViewApi; 2867 }()); 2868 2869 var EVENT_SOURCE_REFINERS$1 = { 2870 id: String, 2871 defaultAllDay: Boolean, 2872 url: String, 2873 format: String,
2874 events: identity, 2875 eventDataTransform: identity, 2876 // for any network-related sources 2877 success: identity, 2878 failure: identity, 2879 }; 2880 function parseEventSource(raw, context, refiners) { 2881 if (refiners === void 0) { refiners = buildEventSourceRefiners(context); } 2882 var rawObj; 2883 if (typeof raw === 'string') { 2884 rawObj = { url: raw }; 2885 } 2886 else if (typeof raw === 'function' || Array.isArray(raw)) { 2887 rawObj = { events: raw }; 2888 } 2889 else if (typeof raw === 'object' && raw) { // not null 2890 rawObj = raw; 2891 } 2892 if (rawObj) { 2893 var _a = refineProps(rawObj, refiners), refined = _a.refined, extra = _a.extra; 2894 var metaRes = buildEventSourceMeta(refined, context); 2895 if (metaRes) { 2896 return { 2897 _raw: raw, 2898 isFetching: false, 2899 latestFetchId: '', 2900 fetchRange: null, 2901 defaultAllDay: refined.defaultAllDay, 2902 eventDataTransform: refined.eventDataTransform, 2903 success: refined.success, 2904 failure: refined.failure, 2905 publicId: refined.id || '', 2906 sourceId: guid(), 2907 sourceDefId: metaRes.sourceDefId, 2908 meta: metaRes.meta, 2909 ui: createEventUi(refined, context), 2910 extendedProps: extra, 2911 }; 2912 } 2913 } 2914 return null; 2915 } 2916 function buildEventSourceRefiners(context) { 2917 return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS$1), context.pluginHooks.eventSourceRefiners); 2918 } 2919 function buildEventSourceMeta(raw, context) { 2920 var defs = context.pluginHooks.eventSourceDefs; 2921 for (var i = defs.length - 1; i >= 0; i -= 1) { // later-added plugins take precedence 2922 var def = defs[i]; 2923 var meta = def.parseMeta(raw); 2924 if (meta) { 2925 return { sourceDefId: i, meta: meta }; 2926 } 2927 } 2928 return null; 2929 } 2930 2931 function reduceCurrentDate(currentDate, action) { 2932 switch (action.type) { 2933 case 'CHANGE_DATE': 2934 return action.dateMarker; 2935 default: 2936 return currentDate; 2937 } 2938 } 2939 function getInitialDate(options, dateEnv) { 2940 var initialDateInput = options.initialDate; 2941 // compute the initial ambig-timezone date 2942 if (initialDateInput != null) { 2943 return dateEnv.createMarker(initialDateInput); 2944 } 2945 return getNow(options.now, dateEnv); // getNow already returns unzoned 2946 } 2947 function getNow(nowInput, dateEnv) { 2948 if (typeof nowInput === 'function') { 2949 nowInput = nowInput(); 2950 } 2951 if (nowInput == null) { 2952 return dateEnv.createNowMarker(); 2953 } 2954 return dateEnv.createMarker(nowInput); 2955 } 2956 2957 var CalendarApi = /** @class */ (function () { 2958 function CalendarApi() { 2959 } 2960 CalendarApi.prototype.getCurrentData = function () { 2961 return this.currentDataManager.getCurrentData(); 2962 }; 2963 CalendarApi.prototype.dispatch = function (action) { 2964 return this.currentDataManager.dispatch(action); 2965 }; 2966 Object.defineProperty(CalendarApi.prototype, "view", { 2967 get: function () { return this.getCurrentData().viewApi; } // for public API 2968 , 2969 enumerable: false, 2970 configurable: true 2971 }); 2972 CalendarApi.prototype.batchRendering = function (callback) { 2973 callback(); 2974 }; 2975 CalendarApi.prototype.updateSize = function () { 2976 this.trigger('_resize', true); 2977 }; 2978 // Options 2979 // ----------------------------------------------------------------------------------------------------------------- 2980 CalendarApi.prototype.setOption = function (name, val) { 2981 this.dispatch({ 2982 type: 'SET_OPTION', 2983 optionName: name, 2984 rawOptionValue: val, 2985 }); 2986 }; 2987 CalendarApi.prototype.getOption = function (name) { 2988 return this.currentDataManager.currentCalendarOptionsInput[name]; 2989 }; 2990 CalendarApi.prototype.getAvailableLocaleCodes = function () { 2991 return Object.keys(this.getCurrentData().availableRawLocales); 2992 }; 2993 // Trigger 2994 // ----------------------------------------------------------------------------------------------------------------- 2995 CalendarApi.prototype.on = function (handlerName, handler) { 2996 var currentDataManager = this.currentDataManager; 2997 if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) { 2998 currentDataManager.emitter.on(handlerName, handler); 2999 } 3000 else { 3001 console.warn("Unknown listener name '" + handlerName + "'"); 3002 } 3003 }; 3004 CalendarApi.prototype.off = function (handlerName, handler) { 3005 this.currentDataManager.emitter.off(handlerName, handler); 3006 }; 3007 // not meant for public use 3008 CalendarApi.prototype.trigger = function (handlerName) { 3009 var _a; 3010 var args = []; 3011 for (var _i = 1; _i < arguments.length; _i++) { 3012 args[_i - 1] = arguments[_i]; 3013 } 3014 (_a = this.currentDataManager.emitter).trigger.apply(_a, __spreadArray([handlerName], args)); 3015 }; 3016 // View 3017 // ----------------------------------------------------------------------------------------------------------------- 3018 CalendarApi.prototype.changeView = function (viewType, dateOrRange) { 3019 var _this = this; 3020 this.batchRendering(function () { 3021 _this.unselect(); 3022 if (dateOrRange) { 3023 if (dateOrRange.start && dateOrRange.end) { // a range 3024 _this.dispatch({ 3025 type: 'CHANGE_VIEW_TYPE', 3026 viewType: viewType, 3027 }); 3028 _this.dispatch({ 3029 type: 'SET_OPTION', 3030 optionName: 'visibleRange', 3031 rawOptionValue: dateOrRange, 3032 }); 3033 } 3034 else { 3035 var dateEnv = _this.getCurrentData().dateEnv; 3036 _this.dispatch({ 3037 type: 'CHANGE_VIEW_TYPE', 3038 viewType: viewType, 3039 dateMarker: dateEnv.createMarker(dateOrRange), 3040 }); 3041 } 3042 } 3043 else { 3044 _this.dispatch({ 3045 type: 'CHANGE_VIEW_TYPE', 3046 viewType: viewType, 3047 }); 3048 } 3049 }); 3050 };
3051 // Forces navigation to a view for the given date. 3052 // `viewType` can be a specific view name or a generic one like "week" or "day". 3053 // needs to change 3054 CalendarApi.prototype.zoomTo = function (dateMarker, viewType) { 3055 var state = this.getCurrentData(); 3056 var spec; 3057 viewType = viewType || 'day'; // day is default zoom 3058 spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType); 3059 this.unselect(); 3060 if (spec) { 3061 this.dispatch({ 3062 type: 'CHANGE_VIEW_TYPE', 3063 viewType: spec.type, 3064 dateMarker: dateMarker, 3065 }); 3066 } 3067 else { 3068 this.dispatch({ 3069 type: 'CHANGE_DATE', 3070 dateMarker: dateMarker, 3071 }); 3072 } 3073 }; 3074 // Given a duration singular unit, like "week" or "day", finds a matching view spec. 3075 // Preference is given to views that have corresponding buttons. 3076 CalendarApi.prototype.getUnitViewSpec = function (unit) { 3077 var _a = this.getCurrentData(), viewSpecs = _a.viewSpecs, toolbarConfig = _a.toolbarConfig; 3078 var viewTypes = [].concat(toolbarConfig.header ? toolbarConfig.header.viewsWithButtons : [], toolbarConfig.footer ? toolbarConfig.footer.viewsWithButtons : []); 3079 var i; 3080 var spec; 3081 for (var viewType in viewSpecs) { 3082 viewTypes.push(viewType); 3083 } 3084 for (i = 0; i < viewTypes.length; i += 1) { 3085 spec = viewSpecs[viewTypes[i]]; 3086 if (spec) { 3087 if (spec.singleUnit === unit) { 3088 return spec; 3089 } 3090 } 3091 } 3092 return null; 3093 }; 3094 // Current Date 3095 // ----------------------------------------------------------------------------------------------------------------- 3096 CalendarApi.prototype.prev = function () { 3097 this.unselect(); 3098 this.dispatch({ type: 'PREV' }); 3099 }; 3100 CalendarApi.prototype.next = function () { 3101 this.unselect(); 3102 this.dispatch({ type: 'NEXT' }); 3103 }; 3104 CalendarApi.prototype.prevYear = function () { 3105 var state = this.getCurrentData(); 3106 this.unselect(); 3107 this.dispatch({ 3108 type: 'CHANGE_DATE', 3109 dateMarker: state.dateEnv.addYears(state.currentDate, -1), 3110 }); 3111 }; 3112 CalendarApi.prototype.nextYear = function () { 3113 var state = this.getCurrentData(); 3114 this.unselect(); 3115 this.dispatch({ 3116 type: 'CHANGE_DATE', 3117 dateMarker: state.dateEnv.addYears(state.currentDate, 1), 3118 }); 3119 }; 3120 CalendarApi.prototype.today = function () { 3121 var state = this.getCurrentData(); 3122 this.unselect(); 3123 this.dispatch({ 3124 type: 'CHANGE_DATE', 3125 dateMarker: getNow(state.calendarOptions.now, state.dateEnv), 3126 }); 3127 }; 3128 CalendarApi.prototype.gotoDate = function (zonedDateInput) { 3129 var state = this.getCurrentData(); 3130 this.unselect(); 3131 this.dispatch({ 3132 type: 'CHANGE_DATE', 3133 dateMarker: state.dateEnv.createMarker(zonedDateInput), 3134 }); 3135 }; 3136 CalendarApi.prototype.incrementDate = function (deltaInput) { 3137 var state = this.getCurrentData(); 3138 var delta = createDuration(deltaInput); 3139 if (delta) { // else, warn about invalid input? 3140 this.unselect(); 3141 this.dispatch({ 3142 type: 'CHANGE_DATE', 3143 dateMarker: state.dateEnv.add(state.currentDate, delta), 3144 }); 3145 } 3146 }; 3147 // for external API 3148 CalendarApi.prototype.getDate = function () { 3149 var state = this.getCurrentData(); 3150 return state.dateEnv.toDate(state.currentDate); 3151 }; 3152 // Date Formatting Utils 3153 // ----------------------------------------------------------------------------------------------------------------- 3154 CalendarApi.prototype.formatDate = function (d, formatter) { 3155 var dateEnv = this.getCurrentData().dateEnv; 3156 return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter)); 3157 }; 3158 // `settings` is for formatter AND isEndExclusive 3159 CalendarApi.prototype.formatRange = function (d0, d1, settings) { 3160 var dateEnv = this.getCurrentData().dateEnv; 3161 return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings), settings); 3162 }; 3163 CalendarApi.prototype.formatIso = function (d, omitTime) { 3164 var dateEnv = this.getCurrentData().dateEnv; 3165 return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime }); 3166 }; 3167 // Date Selection / Event Selection / DayClick 3168 // ----------------------------------------------------------------------------------------------------------------- 3169 // this public method receives start/end dates in any format, with any timezone 3170 // NOTE: args were changed from v3 3171 CalendarApi.prototype.select = function (dateOrObj, endDate) { 3172 var selectionInput; 3173 if (endDate == null) { 3174 if (dateOrObj.start != null) { 3175 selectionInput = dateOrObj; 3176 } 3177 else { 3178 selectionInput = { 3179 start: dateOrObj, 3180 end: null, 3181 }; 3182 } 3183 } 3184 else { 3185 selectionInput = { 3186 start: dateOrObj, 3187 end: endDate, 3188 }; 3189 } 3190 var state = this.getCurrentData(); 3191 var selection = parseDateSpan(selectionInput, state.dateEnv, createDuration({ days: 1 })); 3192 if (selection) { // throw parse error otherwise? 3193 this.dispatch({ type: 'SELECT_DATES', selection: selection }); 3194 triggerDateSelect(selection, null, state); 3195 } 3196 }; 3197 // public method 3198 CalendarApi.prototype.unselect = function (pev) { 3199 var state = this.getCurrentData(); 3200 if (state.dateSelection) { 3201 this.dispatch({ type: 'UNSELECT_DATES' }); 3202 triggerDateUnselect(pev, state); 3203 } 3204 }; 3205 // Public Events API 3206 // ----------------------------------------------------------------------------------------------------------------- 3207 CalendarApi.prototype.addEvent = function (eventInput, sourceIn
3207put) { 3208 if (eventInput instanceof EventApi) { 3209 var def = eventInput._def; 3210 var instance = eventInput._instance; 3211 var currentData = this.getCurrentData(); 3212 // not already present? don't want to add an old snapshot 3213 if (!currentData.eventStore.defs[def.defId]) { 3214 this.dispatch({ 3215 type: 'ADD_EVENTS', 3216 eventStore: eventTupleToStore({ def: def, instance: instance }), // TODO: better util for two args? 3217 }); 3218 this.triggerEventAdd(eventInput); 3219 } 3220 return eventInput; 3221 } 3222 var state = this.getCurrentData(); 3223 var eventSource; 3224 if (sourceInput instanceof EventSourceApi) { 3225 eventSource = sourceInput.internalEventSource; 3226 } 3227 else if (typeof sourceInput === 'boolean') { 3228 if (sourceInput) { // true. part of the first event source 3229 eventSource = hashValuesToArray(state.eventSources)[0]; 3230 } 3231 } 3232 else if (sourceInput != null) { // an ID. accepts a number too 3233 var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function 3234 if (!sourceApi) { 3235 console.warn("Could not find an event source with ID \"" + sourceInput + "\""); // TODO: test 3236 return null; 3237 } 3238 eventSource = sourceApi.internalEventSource; 3239 } 3240 var tuple = parseEvent(eventInput, eventSource, state, false); 3241 if (tuple) { 3242 var newEventApi = new EventApi(state, tuple.def, tuple.def.recurringDef ? null : tuple.instance); 3243 this.dispatch({ 3244 type: 'ADD_EVENTS', 3245 eventStore: eventTupleToStore(tuple), 3246 }); 3247 this.triggerEventAdd(newEventApi); 3248 return newEventApi; 3249 } 3250 return null; 3251 }; 3252 CalendarApi.prototype.triggerEventAdd = function (eventApi) { 3253 var _this = this; 3254 var emitter = this.getCurrentData().emitter; 3255 emitter.trigger('eventAdd', { 3256 event: eventApi, 3257 relatedEvents: [], 3258 revert: function () { 3259 _this.dispatch({ 3260 type: 'REMOVE_EVENTS', 3261 eventStore: eventApiToStore(eventApi), 3262 }); 3263 }, 3264 }); 3265 }; 3266 // TODO: optimize 3267 CalendarApi.prototype.getEventById = function (id) { 3268 var state = this.getCurrentData(); 3269 var _a = state.eventStore, defs = _a.defs, instances = _a.instances; 3270 id = String(id); 3271 for (var defId in defs) { 3272 var def = defs[defId]; 3273 if (def.publicId === id) { 3274 if (def.recurringDef) { 3275 return new EventApi(state, def, null); 3276 } 3277 for (var instanceId in instances) { 3278 var instance = instances[instanceId]; 3279 if (instance.defId === def.defId) { 3280 return new EventApi(state, def, instance); 3281 } 3282 } 3283 } 3284 } 3285 return null; 3286 }; 3287 CalendarApi.prototype.getEvents = function () { 3288 var currentData = this.getCurrentData(); 3289 return buildEventApis(currentData.eventStore, currentData); 3290 }; 3291 CalendarApi.prototype.removeAllEvents = function () { 3292 this.dispatch({ type: 'REMOVE_ALL_EVENTS' }); 3293 }; 3294 // Public Event Sources API 3295 // ----------------------------------------------------------------------------------------------------------------- 3296 CalendarApi.prototype.getEventSources = function () { 3297 var state = this.getCurrentData(); 3298 var sourceHash = state.eventSources; 3299 var sourceApis = []; 3300 for (var internalId in sourceHash) { 3301 sourceApis.push(new EventSourceApi(state, sourceHash[internalId])); 3302 } 3303 return sourceApis; 3304 }; 3305 CalendarApi.prototype.getEventSourceById = function (id) { 3306 var state = this.getCurrentData(); 3307 var sourceHash = state.eventSources; 3308 id = String(id); 3309 for (var sourceId in sourceHash) { 3310 if (sourceHash[sourceId].publicId === id) { 3311 return new EventSourceApi(state, sourceHash[sourceId]); 3312 } 3313 } 3314 return null; 3315 }; 3316 CalendarApi.prototype.addEventSource = function (sourceInput) { 3317 var state = this.getCurrentData(); 3318 if (sourceInput instanceof EventSourceApi) { 3319 // not already present? don't want to add an old snapshot
3320 if (!state.eventSources[sourceInput.internalEventSource.sourceId]) { 3321 this.dispatch({ 3322 type: 'ADD_EVENT_SOURCES', 3323 sources: [sourceInput.internalEventSource], 3324 }); 3325 } 3326 return sourceInput; 3327 } 3328 var eventSource = parseEventSource(sourceInput, state); 3329 if (eventSource) { // TODO: error otherwise? 3330 this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] }); 3331 return new EventSourceApi(state, eventSource); 3332 } 3333 return null; 3334 }; 3335 CalendarApi.prototype.removeAllEventSources = function () { 3336 this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' }); 3337 }; 3338 CalendarApi.prototype.refetchEvents = function () { 3339 this.dispatch({ type: 'FETCH_EVENT_SOURCES', isRefetch: true }); 3340 }; 3341 // Scroll 3342 // ----------------------------------------------------------------------------------------------------------------- 3343 CalendarApi.prototype.scrollToTime = function (timeInput) { 3344 var time = createDuration(timeInput); 3345 if (time) { 3346 this.trigger('_scrollRequest', { time: time }); 3347 } 3348 }; 3349 return CalendarApi; 3350 }()); 3351 3352 var EventApi = /** @class */ (function () { 3353 // instance will be null if expressing a recurring event that has no current instances, 3354 // OR if trying to validate an incoming external event that has no dates assigned 3355 function EventApi(context, def, instance) { 3356 this._context = context; 3357 this._def = def; 3358 this._instance = instance || null; 3359 } 3360 /* 3361 TODO: make event struct more responsible for this 3362 */ 3363 EventApi.prototype.setProp = function (name, val) { 3364 var _a, _b; 3365 if (name in EVENT_DATE_REFINERS) { 3366 console.warn('Could not set date-related prop \'name\'. Use one of the date-related methods instead.'); 3367 // TODO: make proper aliasing system? 3368 } 3369 else if (name === 'id') { 3370 val = EVENT_NON_DATE_REFINERS[name](val); 3371 this.mutate({ 3372 standardProps: { publicId: val }, // hardcoded internal name 3373 }); 3374 } 3375 else if (name in EVENT_NON_DATE_REFINERS) { 3376 val = EVENT_NON_DATE_REFINERS[name](val); 3377 this.mutate({ 3378 standardProps: (_a = {}, _a[name] = val, _a), 3379 }); 3380 } 3381 else if (name in EVENT_UI_REFINERS) { 3382 var ui = EVENT_UI_REFINERS[name](val); 3383 if (name === 'color') { 3384 ui = { backgroundColor: val, borderColor: val }; 3385 } 3386 else if (name === 'editable') { 3387 ui = { startEditable: val, durationEditable: val }; 3388 } 3389 else { 3390 ui = (_b = {}, _b[name] = val, _b); 3391 } 3392 this.mutate({ 3393 standardProps: { ui: ui }, 3394 }); 3395 } 3396 else { 3397 console.warn("Could not set prop '" + name + "'. Use setExtendedProp instead."); 3398 } 3399 }; 3400 EventApi.prototype.setExtendedProp = function (name, val) { 3401 var _a; 3402 this.mutate({ 3403 extendedProps: (_a = {}, _a[name] = val, _a), 3404 }); 3405 }; 3406 EventApi.prototype.setStart = function (startInput, options) { 3407 if (options === void 0) { options = {}; } 3408 var dateEnv = this._context.dateEnv; 3409 var start = dateEnv.createMarker(startInput); 3410 if (start && this._instance) { // TODO: warning if parsed bad 3411 var instanceRange = this._instance.range; 3412 var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!? 3413 if (options.maintainDuration) { 3414 this.mutate({ datesDelta: startDelta }); 3415 } 3416 else { 3417 this.mutate({ startDelta: startDelta }); 3418 } 3419 } 3420 }; 3421 EventApi.prototype.setEnd = function (endInput, options) { 3422 if (options === void 0) { options = {}; } 3423 var dateEnv = this._context.dateEnv; 3424 var end; 3425 if (endInput != null) { 3426 end = dateEnv.createMarker(endInput); 3427 if (!end) { 3428 return; // TODO: warning if parsed bad 3429 } 3430 } 3431 if (this._instance) { 3432 if (end) { 3433 var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity); 3434 this.mutate({ endDelta: endDelta }); 3435 } 3436 else { 3437 this.mutate({ standardProps: { hasEnd: false } }); 3438 } 3439 } 3440 }; 3441 EventApi.prototype.setDates = function (startInput, endInput, options) { 3442 if (options === void 0) { options = {}; } 3443 var dateEnv = this._context.dateEnv; 3444 var standardProps = { allDay: options.allDay }; 3445 var start = dateEnv.createMarker(startInput); 3446 var end; 3447 if (!start) { 3448 return; // TODO: warning if parsed bad 3449 } 3450 if (endInput != null) { 3451 end = dateEnv.createMarker(endInput); 3452 if (!end) { // TODO: warning if parsed bad 3453 return; 3454 } 3455 } 3456 if (this._instance) { 3457 var instanceRange = this._instance.range; 3458 // when computing the diff for an event being converted to all-day, 3459 // compute diff off of the all-day values the way event-mutation does. 3460 if (options.allDay === true) { 3461 instanceRange = computeAlignedDayRange(instanceRange); 3462 } 3463 var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); 3464 if (end) { 3465 var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity); 3466 if (durationsEqual(startDelta, endDelta)) { 3467 this.mutate({ datesDelta: startDelta, standardProps: standardProps }); 3468 } 3469 else { 3470 this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps }); 3471 } 3472 } 3473 else { // means "clear the end" 3474 standardProps.hasEnd = false;
3475 this.mutate({ datesDelta: startDelta, standardProps: standardProps }); 3476 } 3477 } 3478 }; 3479 EventApi.prototype.moveStart = function (deltaInput) { 3480 var delta = createDuration(deltaInput); 3481 if (delta) { // TODO: warning if parsed bad 3482 this.mutate({ startDelta: delta }); 3483 } 3484 }; 3485 EventApi.prototype.moveEnd = function (deltaInput) { 3486 var delta = createDuration(deltaInput); 3487 if (delta) { // TODO: warning if parsed bad 3488 this.mutate({ endDelta: delta }); 3489 } 3490 }; 3491 EventApi.prototype.moveDates = function (deltaInput) { 3492 var delta = createDuration(deltaInput); 3493 if (delta) { // TODO: warning if parsed bad 3494 this.mutate({ datesDelta: delta }); 3495 } 3496 }; 3497 EventApi.prototype.setAllDay = function (allDay, options) { 3498 if (options === void 0) { options = {}; } 3499 var standardProps = { allDay: allDay }; 3500 var maintainDuration = options.maintainDuration; 3501 if (maintainDuration == null) { 3502 maintainDuration = this._context.options.allDayMaintainDuration; 3503 } 3504 if (this._def.allDay !== allDay) { 3505 standardProps.hasEnd = maintainDuration; 3506 } 3507 this.mutate({ standardProps: standardProps }); 3508 }; 3509 EventApi.prototype.formatRange = function (formatInput) { 3510 var dateEnv = this._context.dateEnv; 3511 var instance = this._instance; 3512 var formatter = createFormatter(formatInput); 3513 if (this._def.hasEnd) { 3514 return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, { 3515 forcedStartTzo: instance.forcedStartTzo, 3516 forcedEndTzo: instance.forcedEndTzo, 3517 }); 3518 } 3519 return dateEnv.format(instance.range.start, formatter, { 3520 forcedTzo: instance.forcedStartTzo, 3521 }); 3522 }; 3523 EventApi.prototype.mutate = function (mutation) { 3524 var instance = this._instance; 3525 if (instance) { 3526 var def = this._def; 3527 var context_1 = this._context; 3528 var eventStore_1 = context_1.getCurrentData().eventStore; 3529 var relevantEvents = getRelevantEvents(eventStore_1, instance.instanceId); 3530 var eventConfigBase = { 3531 '': { 3532 display: '', 3533 startEditable: true, 3534 durationEditable: true, 3535 constraints: [], 3536 overlap: null, 3537 allows: [], 3538 backgroundColor: '', 3539 borderColor: '', 3540 textColor: '', 3541 classNames: [], 3542 }, 3543 }; 3544 relevantEvents = applyMutationToEventStore(relevantEvents, eventConfigBase, mutation, context_1); 3545 var oldEvent = new EventApi(context_1, def, instance); // snapshot 3546 this._def = relevantEvents.defs[def.defId]; 3547 this._instance = relevantEvents.instances[instance.instanceId]; 3548 context_1.dispatch({ 3549 type: 'MERGE_EVENTS', 3550 eventStore: relevantEvents, 3551 }); 3552 context_1.emitter.trigger('eventChange', { 3553 oldEvent: oldEvent, 3554 event: this, 3555 relatedEvents: buildEventApis(relevantEvents, context_1, instance), 3556 revert: function () { 3557 context_1.dispatch({ 3558 type: 'RESET_EVENTS', 3559 eventStore: eventStore_1, 3560 }); 3561 }, 3562 }); 3563 } 3564 }; 3565 EventApi.prototype.remove = function () { 3566 var context = this._context; 3567 var asStore = eventApiToStore(this); 3568 context.dispatch({
3569 type: 'REMOVE_EVENTS', 3570 eventStore: asStore, 3571 }); 3572 context.emitter.trigger('eventRemove', { 3573 event: this, 3574 relatedEvents: [], 3575 revert: function () { 3576 context.dispatch({ 3577 type: 'MERGE_EVENTS', 3578 eventStore: asStore, 3579 }); 3580 }, 3581 }); 3582 }; 3583 Object.defineProperty(EventApi.prototype, "source", { 3584 get: function () { 3585 var sourceId = this._def.sourceId; 3586 if (sourceId) { 3587 return new EventSourceApi(this._context, this._context.getCurrentData().eventSources[sourceId]); 3588 } 3589 return null; 3590 }, 3591 enumerable: false, 3592 configurable: true 3593 }); 3594 Object.defineProperty(EventApi.prototype, "start", { 3595 get: function () { 3596 return this._instance ? 3597 this._context.dateEnv.toDate(this._instance.range.start) : 3598 null; 3599 }, 3600 enumerable: false, 3601 configurable: true 3602 }); 3603 Object.defineProperty(EventApi.prototype, "end", { 3604 get: function () { 3605 return (this._instance && this._def.hasEnd) ? 3606 this._context.dateEnv.toDate(this._instance.range.end) : 3607 null; 3608 }, 3609 enumerable: false, 3610 configurable: true 3611 }); 3612 Object.defineProperty(EventApi.prototype, "startStr", { 3613 get: function () { 3614 var instance = this._instance; 3615 if (instance) { 3616 return this._context.dateEnv.formatIso(instance.range.start, { 3617 omitTime: this._def.allDay, 3618 forcedTzo: instance.forcedStartTzo, 3619 }); 3620 } 3621 return ''; 3622 }, 3623 enumerable: false, 3624 configurable: true 3625 }); 3626 Object.defineProperty(EventApi.prototype, "endStr", { 3627 get: function () { 3628 var instance = this._instance; 3629 if (instance && this._def.hasEnd) { 3630 return this._context.dateEnv.formatIso(instance.range.end, { 3631 omitTime: this._def.allDay, 3632 forcedTzo: instance.forcedEndTzo, 3633 }); 3634 } 3635 return ''; 3636 }, 3637 enumerable: false, 3638 configurable: true 3639 }); 3640 Object.defineProperty(EventApi.prototype, "id", { 3641 // computable props that all access the def
3642 // TODO: find a TypeScript-compatible way to do this at scale 3643 get: function () { return this._def.publicId; }, 3644 enumerable: false, 3645 configurable: true 3646 }); 3647 Object.defineProperty(EventApi.prototype, "groupId", { 3648 get: function () { return this._def.groupId; }, 3649 enumerable: false, 3650 configurable: true 3651 }); 3652 Object.defineProperty(EventApi.prototype, "allDay", { 3653 get: function () { return this._def.allDay; }, 3654 enumerable: false, 3655 configurable: true 3656 }); 3657 Object.defineProperty(EventApi.prototype, "title", { 3658 get: function () { return this._def.title; }, 3659 enumerable: false, 3660 configurable: true 3661 }); 3662 Object.defineProperty(EventApi.prototype, "url", { 3663 get: function () { return this._def.url; }, 3664 enumerable: false, 3665 configurable: true 3666 }); 3667 Object.defineProperty(EventApi.prototype, "display", { 3668 get: function () { return this._def.ui.display || 'auto'; } // bad. just normalize the type earlier 3669 , 3670 enumerable: false, 3671 configurable: true 3672 }); 3673 Object.defineProperty(EventApi.prototype, "startEditable", { 3674 get: function () { return this._def.ui.startEditable; }, 3675 enumerable: false, 3676 configurable: true 3677 }); 3678 Object.defineProperty(EventApi.prototype, "durationEditable", { 3679 get: function () { return this._def.ui.durationEditable; }, 3680 enumerable: false, 3681 configurable: true 3682 }); 3683 Object.defineProperty(EventApi.prototype, "constraint", { 3684 get: function () { return this._def.ui.constraints[0] || null; }, 3685 enumerable: false, 3686 configurable: true 3687 }); 3688 Object.defineProperty(EventApi.prototype, "overlap", { 3689 get: function () { return this._def.ui.overlap; }, 3690 enumerable: false, 3691 configurable: true 3692 }); 3693 Object.defineProperty(EventApi.prototype, "allow", { 3694 get: function () { return this._def.ui.allows[0] || null; }, 3695 enumerable: false, 3696 configurable: true 3697 }); 3698 Object.defineProperty(EventApi.prototype, "backgroundColor", { 3699 get: function () { return this._def.ui.backgroundColor; }, 3700 enumerable: false, 3701 configurable: true 3702 }); 3703 Object.defineProperty(EventApi.prototype, "borderColor", { 3704 get: function () { return this._def.ui.borderColor; }, 3705 enumerable: false, 3706 configurable: true 3707 }); 3708 Object.defineProperty(EventApi.prototype, "textColor", { 3709 get: function () { return this._def.ui.textColor; }, 3710 enumerable: false, 3711 configurable: true 3712 }); 3713 Object.defineProperty(EventApi.prototype, "classNames", { 3714 // NOTE: user can't modify these because Object.freeze was called in event-def parsing 3715 get: function () { return this._def.ui.classNames; }, 3716 enumerable: false, 3717 configurable: true 3718 }); 3719 Object.defineProperty(EventApi.prototype, "extendedProps", { 3720 get: function () { return this._def.extendedProps; }, 3721 enumerable: false, 3722 configurable: true 3723 }); 3724 EventApi.prototype.toPlainObject = function (settings) { 3725 if (settings === void 0) { settings = {}; } 3726 var def = this._def; 3727 var ui = def.ui; 3728 var _a = this, startStr = _a.startStr, endStr = _a.endStr; 3729 var res = {}; 3730 if (def.title) { 3731 res.title = def.title; 3732 } 3733 if (startStr) { 3734 res.start = startStr; 3735 } 3736 if (endStr) { 3737 res.end = endStr; 3738 } 3739 if (def.publicId) { 3740 res.id = def.publicId; 3741 } 3742 if (def.groupId) { 3743 res.groupId = def.groupId; 3744 } 3745 if (def.url) { 3746 res.url = def.url; 3747 } 3748 if (ui.display && ui.display !== 'auto') { 3749 res.display = ui.display; 3750 } 3751 // TODO: what about recurring-event properties??? 3752 // TODO: include startEditable/durationEditable/constraint/overlap/allow 3753 if (settings.collapseColor && ui.backgroundColor && ui.backgroundColor === ui.borderColor) { 3754 res.color = ui.backgroundColor; 3755 } 3756 else { 3757 if (ui.backgroundColor) { 3758 res.backgroundColor = ui.backgroundColor; 3759 } 3760 if (ui.borderColor) { 3761 res.borderColor = ui.borderColor; 3762 } 3763 } 3764 if (ui.textColor) { 3765 res.textColor = ui.textColor; 3766 } 3767 if (ui.classNames.length) { 3768 res.classNames = ui.classNames; 3769 } 3770 if (Object.keys(def.extendedProps).length) { 3771 if (settings.collapseExtendedProps) { 3772 __assign(res, def.extendedProps); 3773 } 3774 else { 3775 res.extendedProps = def.extendedProps; 3776 } 3777 } 3778 return res; 3779 }; 3780 EventApi.prototype.toJSON = function () { 3781 return this.toPlainObject(); 3782 }; 3783 return EventApi; 3784 }()); 3785 function eventApiToStore(eventApi) { 3786 var _a, _b; 3787 var def = eventApi._def; 3788 var instance = eventApi._instance; 3789 return { 3790 defs: (_a = {}, _a[def.defId] = def, _a), 3791 instances: instance 3792 ? (_b = {}, _b[instance.instanceId] = instance, _b) : {}, 3793 }; 3794 } 3795 function buildEventApis(eventStore, context, excludeInstance) { 3796 var defs = eventStore.defs, instances = eventStore.instances; 3797 var eventApis = []; 3798 var excludeInstanceId = excludeInstance ? excludeInstance.instanceId : ''; 3799 for (var id in instances) { 3800 var instance = instances[id]; 3801 var def = defs[instance.defId]; 3802 if (instance.instanceId !== excludeInstanceId) { 3803 eventApis.push(new EventApi(context, def, instance)); 3804 } 3805 } 3806 return eventApis; 3807 } 3808 3809 var calendarSystemClassMap = {}; 3810 function registerCalendarSystem(name, theClass) { 3811 calendarSystemClassMap[name] = theClass; 3812 } 3813 function createCalendarSystem(name) { 3814 return new calendarSystemClassMap[name](); 3815 } 3816 var GregorianCalendarSystem = /** @class */ (function () { 3817 function GregorianCalendarSystem() { 3818 } 3819 GregorianCalendarSystem.prototype.getMarkerYear = function (d) { 3820 return d.getUTCFullYear(); 3821 }; 3822 GregorianCalendarSystem.prototype.getMarkerMonth = function (d) { 3823 return d.getUTCMonth(); 3824 }; 3825 GregorianCalendarSystem.prototype.getMarkerDay = function (d) { 3826 return d.getUTCDate(); 3827 }; 3828 GregorianCalendarSystem.prototype.arrayToMarker = function (arr) { 3829 return arrayToUtcDate(arr); 3830 }; 3831 GregorianCalendarSystem.prototype.markerToArray = function (marker) { 3832 return dateToUtcArray(marker); 3833 }; 3834 return GregorianCalendarSystem; 3835 }()); 3836 registerCalendarSystem('gregory', GregorianCalendarSystem); 3837 3838 var ISO_RE = /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/; 3839 function parse(str) { 3840 var m = ISO_RE.exec(str); 3841 if (m) { 3842 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)); 3843 if (isValidDate(marker)) { 3844 var timeZoneOffset = null; 3845 if (m[13]) { 3846 timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 + 3847 Number(m[18] || 0)); 3848 } 3849 return { 3850 marker: marker, 3851 isTimeUnspecified: !m[6], 3852 timeZoneOffset: timeZoneOffset, 3853 }; 3854 } 3855 } 3856 return null; 3857 } 3858 3859 var DateEnv = /** @class */ (function () { 3860 function DateEnv(settings) { 3861 var timeZone = this.timeZone = settings.timeZone; 3862 var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC'; 3863 if (settings.namedTimeZoneImpl && isNamedTimeZone) { 3864 this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone); 3865 } 3866 this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl); 3867 this.calendarSystem = createCalendarSystem(settings.calendarSystem); 3868 this.locale = settings.locale; 3869 this.weekDow = settings.locale.week.dow; 3870 this.weekDoy = settings.locale.week.doy; 3871 if (settings.weekNumberCalculation === 'ISO') { 3872 this.weekDow = 1; 3873 this.weekDoy = 4; 3874 } 3875 if (typeof settings.firstDay === 'number') { 3876 this.weekDow = settings.firstDay; 3877 } 3878 if (typeof settings.weekNumberCalculation === 'function') {
vendor: 13,323 bytes, lines 3879-4214
3879 this.weekNumberFunc = settings.weekNumberCalculation; 3880 } 3881 this.weekText = settings.weekText != null ? settings.weekText : settings.locale.options.weekText; 3882 this.weekTextLong = (settings.weekTextLong != null ? settings.weekTextLong : settings.locale.options.weekTextLong) || this.weekText; 3883 this.cmdFormatter = settings.cmdFormatter; 3884 this.defaultSeparator = settings.defaultSeparator; 3885 } 3886 // Creating / Parsing 3887 DateEnv.prototype.createMarker = function (input) { 3888 var meta = this.createMarkerMeta(input); 3889 if (meta === null) { 3890 return null; 3891 } 3892 return meta.marker; 3893 }; 3894 DateEnv.prototype.createNowMarker = function () { 3895 if (this.canComputeOffset) { 3896 return this.timestampToMarker(new Date().valueOf()); 3897 } 3898 // if we can't compute the current date val for a timezone, 3899 // better to give the current local date vals than UTC 3900 return arrayToUtcDate(dateToLocalArray(new Date())); 3901 }; 3902 DateEnv.prototype.createMarkerMeta = function (input) { 3903 if (typeof input === 'string') { 3904 return this.parse(input); 3905 } 3906 var marker = null; 3907 if (typeof input === 'number') { 3908 marker = this.timestampToMarker(input); 3909 } 3910 else if (input instanceof Date) { 3911 input = input.valueOf(); 3912 if (!isNaN(input)) { 3913 marker = this.timestampToMarker(input); 3914 } 3915 } 3916 else if (Array.isArray(input)) { 3917 marker = arrayToUtcDate(input); 3918 } 3919 if (marker === null || !isValidDate(marker)) { 3920 return null; 3921 } 3922 return { marker: marker, isTimeUnspecified: false, forcedTzo: null }; 3923 }; 3924 DateEnv.prototype.parse = function (s) { 3925 var parts = parse(s); 3926 if (parts === null) { 3927 return null; 3928 } 3929 var marker = parts.marker; 3930 var forcedTzo = null; 3931 if (parts.timeZoneOffset !== null) { 3932 if (this.canComputeOffset) { 3933 marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000); 3934 } 3935 else { 3936 forcedTzo = parts.timeZoneOffset; 3937 } 3938 } 3939 return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo }; 3940 }; 3941 // Accessors 3942 DateEnv.prototype.getYear = function (marker) { 3943 return this.calendarSystem.getMarkerYear(marker); 3944 }; 3945 DateEnv.prototype.getMonth = function (marker) { 3946 return this.calendarSystem.getMarkerMonth(marker); 3947 }; 3948 // Adding / Subtracting 3949 DateEnv.prototype.add = function (marker, dur) { 3950 var a = this.calendarSystem.markerToArray(marker); 3951 a[0] += dur.years; 3952 a[1] += dur.months; 3953 a[2] += dur.days; 3954 a[6] += dur.milliseconds; 3955 return this.calendarSystem.arrayToMarker(a); 3956 }; 3957 DateEnv.prototype.subtract = function (marker, dur) { 3958 var a = this.calendarSystem.markerToArray(marker); 3959 a[0] -= dur.years; 3960 a[1] -= dur.months; 3961 a[2] -= dur.days; 3962 a[6] -= dur.milliseconds; 3963 return this.calendarSystem.arrayToMarker(a); 3964 }; 3965 DateEnv.prototype.addYears = function (marker, n) { 3966 var a = this.calendarSystem.markerToArray(marker); 3967 a[0] += n; 3968 return this.calendarSystem.arrayToMarker(a); 3969 }; 3970 DateEnv.prototype.addMonths = function (marker, n) { 3971 var a = this.calendarSystem.markerToArray(marker); 3972 a[1] += n; 3973 return this.calendarSystem.arrayToMarker(a); 3974 }; 3975 // Diffing Whole Units 3976 DateEnv.prototype.diffWholeYears = function (m0, m1) { 3977 var calendarSystem = this.calendarSystem; 3978 if (timeAsMs(m0) === timeAsMs(m1) && 3979 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) && 3980 calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) { 3981 return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0); 3982 } 3983 return null; 3984 }; 3985 DateEnv.prototype.diffWholeMonths = function (m0, m1) { 3986 var calendarSystem = this.calendarSystem; 3987 if (timeAsMs(m0) === timeAsMs(m1) && 3988 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) { 3989 return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) + 3990 (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12; 3991 } 3992 return null; 3993 }; 3994 // Range / Duration 3995 DateEnv.prototype.greatestWholeUnit = function (m0, m1) { 3996 var n = this.diffWholeYears(m0, m1); 3997 if (n !== null) { 3998 return { unit: 'year', value: n }; 3999 } 4000 n = this.diffWholeMonths(m0, m1); 4001 if (n !== null) { 4002 return { unit: 'month', value: n }; 4003 } 4004 n = diffWholeWeeks(m0, m1); 4005 if (n !== null) { 4006 return { unit: 'week', value: n }; 4007 } 4008 n = diffWholeDays(m0, m1); 4009 if (n !== null) { 4010 return { unit: 'day', value: n }; 4011 } 4012 n = diffHours(m0, m1); 4013 if (isInt(n)) { 4014 return { unit: 'hour', value: n }; 4015 } 4016 n = diffMinutes(m0, m1); 4017 if (isInt(n)) { 4018 return { unit: 'minute', value: n }; 4019 } 4020 n = diffSeconds(m0, m1); 4021 if (isInt(n)) { 4022 return { unit: 'second', value: n }; 4023 } 4024 return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() }; 4025 }; 4026 DateEnv.prototype.countDurationsBetween = function (m0, m1, d) { 4027 // TODO: can use greatestWholeUnit 4028 var diff; 4029 if (d.years) { 4030 diff = this.diffWholeYears(m0, m1); 4031 if (diff !== null) { 4032 return diff / asRoughYears(d); 4033 } 4034 } 4035 if (d.months) { 4036 diff = this.diffWholeMonths(m0, m1); 4037 if (diff !== null) { 4038 return diff / asRoughMonths(d); 4039 } 4040 } 4041 if (d.days) { 4042 diff = diffWholeDays(m0, m1); 4043 if (diff !== null) { 4044 return diff / asRoughDays(d); 4045 } 4046 } 4047 return (m1.valueOf() - m0.valueOf()) / asRoughMs(d); 4048 }; 4049 // Start-Of 4050 // these DON'T return zoned-dates. only UTC start-of dates 4051 DateEnv.prototype.startOf = function (m, unit) { 4052 if (unit === 'year') { 4053 return this.startOfYear(m); 4054 } 4055 if (unit === 'month') { 4056 return this.startOfMonth(m); 4057 } 4058 if (unit === 'week') { 4059 return this.startOfWeek(m); 4060 } 4061 if (unit === 'day') { 4062 return startOfDay(m); 4063 } 4064 if (unit === 'hour') { 4065 return startOfHour(m); 4066 } 4067 if (unit === 'minute') { 4068 return startOfMinute(m); 4069 } 4070 if (unit === 'second') { 4071 return startOfSecond(m); 4072 } 4073 return null; 4074 }; 4075 DateEnv.prototype.startOfYear = function (m) { 4076 return this.calendarSystem.arrayToMarker([ 4077 this.calendarSystem.getMarkerYear(m), 4078 ]); 4079 }; 4080 DateEnv.prototype.startOfMonth = function (m) { 4081 return this.calendarSystem.arrayToMarker([ 4082 this.calendarSystem.getMarkerYear(m), 4083 this.calendarSystem.getMarkerMonth(m), 4084 ]); 4085 }; 4086 DateEnv.prototype.startOfWeek = function (m) { 4087 return this.calendarSystem.arrayToMarker([ 4088 this.calendarSystem.getMarkerYear(m), 4089 this.calendarSystem.getMarkerMonth(m), 4090 m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7), 4091 ]); 4092 }; 4093 // Week Number 4094 DateEnv.prototype.computeWeekNumber = function (marker) { 4095 if (this.weekNumberFunc) { 4096 return this.weekNumberFunc(this.toDate(marker)); 4097 } 4098 return weekOfYear(marker, this.weekDow, this.weekDoy); 4099 }; 4100 // TODO: choke on timeZoneName: long 4101 DateEnv.prototype.format = function (marker, formatter, dateOptions) { 4102 if (dateOptions === void 0) { dateOptions = {}; } 4103 return formatter.format({ 4104 marker: marker, 4105 timeZoneOffset: dateOptions.forcedTzo != null ? 4106 dateOptions.forcedTzo : 4107 this.offsetForMarker(marker), 4108 }, this); 4109 }; 4110 DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) { 4111 if (dateOptions === void 0) { dateOptions = {}; } 4112 if (dateOptions.isEndExclusive) { 4113 end = addMs(end, -1); 4114 } 4115 return formatter.formatRange({ 4116 marker: start, 4117 timeZoneOffset: dateOptions.forcedStartTzo != null ? 4118 dateOptions.forcedStartTzo : 4119 this.offsetForMarker(start), 4120 }, { 4121 marker: end, 4122 timeZoneOffset: dateOptions.forcedEndTzo != null ? 4123 dateOptions.forcedEndTzo : 4124 this.offsetForMarker(end), 4125 }, this, dateOptions.defaultSeparator); 4126 }; 4127 /* 4128 DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that, 4129 might as well use buildIsoString or some other util directly 4130 */ 4131 DateEnv.prototype.formatIso = function (marker, extraOptions) { 4132 if (extraOptions === void 0) { extraOptions = {}; } 4133 var timeZoneOffset = null; 4134 if (!extraOptions.omitTimeZoneOffset) { 4135 if (extraOptions.forcedTzo != null) { 4136 timeZoneOffset = extraOptions.forcedTzo; 4137 } 4138 else { 4139 timeZoneOffset = this.offsetForMarker(marker); 4140 } 4141 } 4142 return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime); 4143 }; 4144 // TimeZone 4145 DateEnv.prototype.timestampToMarker = function (ms) { 4146 if (this.timeZone === 'local') { 4147 return arrayToUtcDate(dateToLocalArray(new Date(ms))); 4148 } 4149 if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) { 4150 return new Date(ms); 4151 } 4152 return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms)); 4153 }; 4154 DateEnv.prototype.offsetForMarker = function (m) { 4155 if (this.timeZone === 'local') { 4156 return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset 4157 } 4158 if (this.timeZone === 'UTC') { 4159 return 0; 4160 } 4161 if (this.namedTimeZoneImpl) { 4162 return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)); 4163 } 4164 return null; 4165 }; 4166 // Conversion 4167 DateEnv.prototype.toDate = function (m, forcedTzo) { 4168 if (this.timeZone === 'local') { 4169 return arrayToLocalDate(dateToUtcArray(m)); 4170 } 4171 if (this.timeZone === 'UTC') { 4172 return new Date(m.valueOf()); // make sure it's a copy 4173 } 4174 if (!this.namedTimeZoneImpl) { 4175 return new Date(m.valueOf() - (forcedTzo || 0)); 4176 } 4177 return new Date(m.valueOf() - 4178 this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60); 4179 }; 4180 return DateEnv; 4181 }()); 4182 4183 var globalLocales = []; 4184 4185 var MINIMAL_RAW_EN_LOCALE = { 4186 code: 'en', 4187 week: { 4188 dow: 0, 4189 doy: 4, // 4 days need to be within the year to be considered the first week 4190 }, 4191 direction: 'ltr', 4192 buttonText: { 4193 prev: 'prev', 4194 next: 'next', 4195 prevYear: 'prev year', 4196 nextYear: 'next year', 4197 year: 'year', 4198 today: 'today', 4199 month: 'month', 4200 week: 'week', 4201 day: 'day', 4202 list: 'list', 4203 }, 4204 weekText: 'W', 4205 weekTextLong: 'Week', 4206 closeHint: 'Close', 4207 timeHint: 'Time', 4208 eventHint: 'Event', 4209 allDayText: 'all-day', 4210 moreLinkText: 'more', 4211 noEventsText: 'No events to display', 4212 }; 4213 var RAW_EN_LOCALE = __assign(__assign({}, MINIMAL_RAW_EN_LOCALE), { 4214 // Includes things we don't want other locales to inherit,
4215 // things that derive from other translatable strings. 4216 buttonHints: { 4217 prev: 'Previous $0', 4218 next: 'Next $0', 4219 today: function (buttonText, unit) { 4220 return (unit === 'day') 4221 ? 'Today' 4222 : "This " + buttonText; 4223 }, 4224 }, viewHint: '$0 view', navLinkHint: 'Go to $0', moreLinkHint: function (eventCnt) { 4225 return "Show " + eventCnt + " more event" + (eventCnt === 1 ? '' : 's'); 4226 } }); 4227 function organizeRawLocales(explicitRawLocales) { 4228 var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en'; 4229 var allRawLocales = globalLocales.concat(explicitRawLocales); 4230 var rawLocaleMap = { 4231 en: RAW_EN_LOCALE, 4232 }; 4233 for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) { 4234 var rawLocale = allRawLocales_1[_i]; 4235 rawLocaleMap[rawLocale.code] = rawLocale; 4236 } 4237 return { 4238 map: rawLocaleMap, 4239 defaultCode: defaultCode, 4240 }; 4241 } 4242 function buildLocale(inputSingular, available) { 4243 if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) { 4244 return parseLocale(inputSingular.code, [inputSingular.code], inputSingular); 4245 } 4246 return queryLocale(inputSingular, available); 4247 } 4248 function queryLocale(codeArg, available) { 4249 var codes = [].concat(codeArg || []); // will convert to array 4250 var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE; 4251 return parseLocale(codeArg, codes, raw); 4252 } 4253 function queryRawLocale(codes, available) { 4254 for (var i = 0; i < codes.length; i += 1) { 4255 var parts = codes[i].toLocaleLowerCase().split('-'); 4256 for (var j = parts.length; j > 0; j -= 1) { 4257 var simpleId = parts.slice(0, j).join('-'); 4258 if (available[simpleId]) { 4259 return available[simpleId]; 4260 } 4261 } 4262 } 4263 return null; 4264 } 4265 function parseLocale(codeArg, codes, raw) { 4266 var merged = mergeProps([MINIMAL_RAW_EN_LOCALE, raw], ['buttonText']); 4267 delete merged.code; // don't want this part of the options 4268 var week = merged.week; 4269 delete merged.week; 4270 return { 4271 codeArg: codeArg, 4272 codes: codes, 4273 week: week, 4274 simpleNumberFormat: new Intl.NumberFormat(codeArg), 4275 options: merged, 4276 }; 4277 } 4278 4279 function formatDate(dateInput, options) { 4280 if (options === void 0) { options = {}; } 4281 var dateEnv = buildDateEnv$1(options); 4282 var formatter = createFormatter(options); 4283 var dateMeta = dateEnv.createMarkerMeta(dateInput); 4284 if (!dateMeta) { // TODO: warning? 4285 return ''; 4286 } 4287 return dateEnv.format(dateMeta.marker, formatter, { 4288 forcedTzo: dateMeta.forcedTzo, 4289 }); 4290 } 4291 function formatRange(startInput, endInput, options) { 4292 var dateEnv = buildDateEnv$1(typeof options === 'object' && options ? options : {}); // pass in if non-null object 4293 var formatter = createFormatter(options); 4294 var startMeta = dateEnv.createMarkerMeta(startInput); 4295 var endMeta = dateEnv.createMarkerMeta(endInput); 4296 if (!startMeta || !endMeta) { // TODO: warning? 4297 return ''; 4298 } 4299 return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, { 4300 forcedStartTzo: startMeta.forcedTzo, 4301 forcedEndTzo: endMeta.forcedTzo, 4302 isEndExclusive: options.isEndExclusive, 4303 defaultSeparator: BASE_OPTION_DEFAULTS.defaultRangeSeparator, 4304 }); 4305 } 4306 // TODO: more DRY and optimized 4307 function buildDateEnv$1(settings) { 4308 var locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere 4309 return new DateEnv(__assign(__assign({ timeZone: BASE_OPTION_DEFAULTS.timeZone, calendarSystem: 'gregory' }, settings), { locale: locale })); 4310 } 4311 4312 var DEF_DEFAULTS = { 4313 startTime: '09:00', 4314 endTime: '17:00', 4315 daysOfWeek: [1, 2, 3, 4, 5], 4316 display: 'inverse-background', 4317 classNames: 'fc-non-business', 4318 groupId: '_businessHours', // so multiple defs get grouped 4319 }; 4320 /* 4321 TODO: pass around as EventDefHash!!! 4322 */ 4323 function parseBusinessHours(input, context) { 4324 return parseEvents(refineInputs(input), null, context); 4325 } 4326 function refineInputs(input) { 4327 var rawDefs; 4328 if (input === true) { 4329 rawDefs = [{}]; // will get DEF_DEFAULTS verbatim 4330 } 4331 else if (Array.isArray(input)) { 4332 // if specifying an array, every sub-definition NEEDS a day-of-week 4333 rawDefs = input.filter(function (rawDef) { return rawDef.daysOfWeek; }); 4334 } 4335 else if (typeof input === 'object' && input) { // non-null object 4336 rawDefs = [input]; 4337 } 4338 else { // is probably false 4339 rawDefs = []; 4340 } 4341 rawDefs = rawDefs.map(function (rawDef) { return (__assign(__assign({}, DEF_DEFAULTS), rawDef)); }); 4342 return rawDefs; 4343 } 4344 4345 function pointInsideRect(point, rect) { 4346 return point.left >= rect.left && 4347 point.left < rect.right && 4348 point.top >
4348= rect.top && 4349 point.top < rect.bottom; 4350 } 4351 // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false 4352 function intersectRects(rect1, rect2) { 4353 var res = { 4354 left: Math.max(rect1.left, rect2.left), 4355 right: Math.min(rect1.right, rect2.right), 4356 top: Math.max(rect1.top, rect2.top), 4357 bottom: Math.min(rect1.bottom, rect2.bottom), 4358 }; 4359 if (res.left < res.right && res.top < res.bottom) { 4360 return res; 4361 } 4362 return false; 4363 } 4364 function translateRect(rect, deltaX, deltaY) { 4365 return { 4366 left: rect.left + deltaX, 4367 right: rect.right + deltaX, 4368 top: rect.top + deltaY, 4369 bottom: rect.bottom + deltaY, 4370 }; 4371 } 4372 // Returns a new point that will have been moved to reside within the given rectangle 4373 function constrainPoint(point, rect) { 4374 return { 4375 left: Math.min(Math.max(point.left, rect.left), rect.right), 4376 top: Math.min(Math.max(point.top, rect.top), rect.bottom), 4377 }; 4378 } 4379 // Returns a point that is the center of the given rectangle 4380 function getRectCenter(rect) { 4381 return { 4382 left: (rect.left + rect.right) / 2, 4383 top: (rect.top + rect.bottom) / 2, 4384 }; 4385 } 4386 // Subtracts point2's coordinates from point1's coordinates, returning a delta 4387 function diffPoints(point1, point2) { 4388 return { 4389 left: point1.left - point2.left, 4390 top: point1.top - point2.top, 4391 }; 4392 } 4393 4394 var canVGrowWithinCell; 4395 function getCanVGrowWithinCell() { 4396 if (canVGrowWithinCell == null) { 4397 canVGrowWithinCell = computeCanVGrowWithinCell(); 4398 } 4399 return canVGrowWithinCell; 4400 } 4401 function computeCanVGrowWithinCell() { 4402 // for SSR, because this function is call immediately at top-level 4403 // TODO: just make this logic execute top-level, immediately, instead of doing lazily 4404 if (typeof document === 'undefined') { 4405 return true; 4406 } 4407 var el = document.createElement('div'); 4408 el.style.position = 'absolute'; 4409 el.style.top = '0px'; 4410 el.style.left = '0px'; 4411 el.innerHTML = '<table><tr><td><div></div></td></tr></table>'; 4412 el.querySelector('table').style.height = '100px'; 4413 el.querySelector('div').style.height = '100%'; 4414 document.body.appendChild(el); 4415 var div = el.querySelector('div'); 4416 var possible = div.offsetHeight > 0; 4417 document.body.removeChild(el); 4418 return possible; 4419 } 4420 4421 var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere 4422 var Splitter = /** @class */ (function () { 4423 function Splitter() { 4424 this.getKeysForEventDefs = memoize(this._getKeysForEventDefs); 4425 this.splitDateSelection = memoize(this._splitDateSpan); 4426 this.splitEventStore = memoize(this._splitEventStore); 4427 this.splitIndividualUi = memoize(this._splitIndividualUi); 4428 this.splitEventDrag = memoize(this._splitInteraction); 4429 this.splitEventResize = memoize(this._splitInteraction); 4430 this.eventUiBuilders = {}; // TODO: typescript protection 4431 } 4432 Splitter.prototype.splitProps = function (props) { 4433 var _this = this; 4434 var keyInfos = this.getKeyInfo(props); 4435 var defKeys = this.getKeysForEventDefs(props.eventStore); 4436 var dateSelections = this.splitDateSelection(props.dateSelection); 4437 var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases* 4438 var eventStores = this.splitEventStore(props.eventStore, defKeys); 4439 var eventDrags = this.splitEventDrag(props.eventDrag); 4440 var eventResizes = this.splitEventResize(props.eventResize); 4441 var splitProps = {}; 4442 this.eventUiBuilders = mapHash(keyInfos, function (info, key) { return _this.eventUiBuilders[key] || memoize(buildEventUiForKey); }); 4443 for (var key in keyInfos) { 4444 var keyInfo = keyInfos[key]; 4445 var eventStore = eventStores[key] || EMPTY_EVENT_STORE; 4446 var buildEventUi = this.eventUiBuilders[key]; 4447 splitProps[key] = { 4448 businessHours: keyInfo.businessHours || props.businessHours, 4449 dateSelection: dateSelections[key] || null, 4450 eventStore: eventStore, 4451 eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]), 4452 eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '', 4453 eventDrag: eventDrags[key] || null, 4454 eventResize: eventResizes[key] || null, 4455 }; 4456 } 4457 return splitProps; 4458 }; 4459 Splitter.prototype._splitDateSpan = function (dateSpan) { 4460 var dateSpans = {}; 4461 if (dateSpan) {
4462 var keys = this.getKeysForDateSpan(dateSpan); 4463 for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { 4464 var key = keys_1[_i]; 4465 dateSpans[key] = dateSpan; 4466 } 4467 } 4468 return dateSpans; 4469 }; 4470 Splitter.prototype._getKeysForEventDefs = function (eventStore) { 4471 var _this = this; 4472 return mapHash(eventStore.defs, function (eventDef) { return _this.getKeysForEventDef(eventDef); }); 4473 }; 4474 Splitter.prototype._splitEventStore = function (eventStore, defKeys) { 4475 var defs = eventStore.defs, instances = eventStore.instances; 4476 var splitStores = {}; 4477 for (var defId in defs) { 4478 for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) { 4479 var key = _a[_i]; 4480 if (!splitStores[key]) { 4481 splitStores[key] = createEmptyEventStore(); 4482 } 4483 splitStores[key].defs[defId] = defs[defId]; 4484 } 4485 } 4486 for (var instanceId in instances) { 4487 var instance = instances[instanceId]; 4488 for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) { 4489 var key = _c[_b]; 4490 if (splitStores[key]) { // must have already been created 4491 splitStores[key].instances[instanceId] = instance; 4492 } 4493 } 4494 } 4495 return splitStores; 4496 }; 4497 Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) { 4498 var splitHashes = {}; 4499 for (var defId in eventUiBases) { 4500 if (defId) { // not the '' key 4501 for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) { 4502 var key = _a[_i]; 4503 if (!splitHashes[key]) { 4504 splitHashes[key] = {}; 4505 } 4506 splitHashes[key][defId] = eventUiBases[defId]; 4507 } 4508 } 4509 } 4510 return splitHashes; 4511 }; 4512 Splitter.prototype._splitInteraction = function (interaction) { 4513 var splitStates = {}; 4514 if (interaction) { 4515 var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents)); 4516 // can't rely on defKeys because event data is mutated 4517 var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents); 4518 var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId); 4519 var populate = function (key) { 4520 if (!splitStates[key]) { 4521 splitStates[key] = { 4522 affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE, 4523 mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE, 4524 isEvent: interaction.isEvent, 4525 }; 4526 } 4527 }; 4528 for (var key in affectedStores_1) { 4529 populate(key); 4530 } 4531 for (var key in mutatedStores_1) { 4532 populate(key); 4533 } 4534 } 4535 return splitStates; 4536 }; 4537 return Splitter; 4538 }()); 4539 function buildEventUiForKey(allUi, eventUiForKey, individualUi) { 4540 var baseParts = []; 4541 if (allUi) { 4542 baseParts.push(allUi); 4543 } 4544 if (eventUiForKey) { 4545 baseParts.push(eventUiForKey); 4546 } 4547 var stuff = { 4548 '': combineEventUis(baseParts), 4549 }; 4550 if (individualUi) { 4551 __assign(stuff, individualUi); 4552 } 4553 return stuff; 4554 } 4555 4556 function getDateMeta(date, todayRange, nowDate, dateProfile) { 4557 return { 4558 dow: date.getUTCDay(), 4559 isDisabled: Boolean(dateProfile && !rangeContainsMarker(dateProfile.activeRange, date)), 4560 isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)), 4561 isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)), 4562 isPast: Boolean(nowDate ? (date < nowDate) : todayRange ? (date < todayRange.start) : false), 4563 isFuture: Boolean(nowDate ? (date > nowDate) : todayRange ? (date >= todayRange.end) : false), 4564 }; 4565 } 4566 function getDayClassNames(meta, theme) { 4567 var classNames = [ 4568 'fc-day',
4569 "fc-day-" + DAY_IDS[meta.dow], 4570 ]; 4571 if (meta.isDisabled) { 4572 classNames.push('fc-day-disabled'); 4573 } 4574 else { 4575 if (meta.isToday) { 4576 classNames.push('fc-day-today'); 4577 classNames.push(theme.getClass('today')); 4578 } 4579 if (meta.isPast) { 4580 classNames.push('fc-day-past'); 4581 } 4582 if (meta.isFuture) { 4583 classNames.push('fc-day-future'); 4584 } 4585 if (meta.isOther) { 4586 classNames.push('fc-day-other'); 4587 } 4588 } 4589 return classNames; 4590 } 4591 function getSlotClassNames(meta, theme) { 4592 var classNames = [ 4593 'fc-slot', 4594 "fc-slot-" + DAY_IDS[meta.dow], 4595 ]; 4596 if (meta.isDisabled) { 4597 classNames.push('fc-slot-disabled'); 4598 } 4599 else { 4600 if (meta.isToday) { 4601 classNames.push('fc-slot-today'); 4602 classNames.push(theme.getClass('today')); 4603 } 4604 if (meta.isPast) { 4605 classNames.push('fc-slot-past'); 4606 } 4607 if (meta.isFuture) { 4608 classNames.push('fc-slot-future'); 4609 } 4610 } 4611 return classNames; 4612 } 4613 4614 var DAY_FORMAT = createFormatter({ year: 'numeric', month: 'long', day: 'numeric' }); 4615 var WEEK_FORMAT = createFormatter({ week: 'long' }); 4616 function buildNavLinkAttrs(context, dateMarker, viewType, isTabbable) { 4617 if (viewType === void 0) { viewType = 'day'; } 4618 if (isTabbable === void 0) { isTabbable = true; } 4619 var dateEnv = context.dateEnv, options = context.options, calendarApi = context.calendarApi; 4620 var dateStr = dateEnv.format(dateMarker, viewType === 'week' ? WEEK_FORMAT : DAY_FORMAT); 4621 if (options.navLinks) { 4622 var zonedDate = dateEnv.toDate(dateMarker); 4623 var handleInteraction = function (ev) { 4624 var customAction = viewType === 'day' ? options.navLinkDayClick : 4625 viewType === 'week' ? options.navLinkWeekClick : null; 4626 if (typeof customAction === 'function') { 4627 customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev); 4628 } 4629 else { 4630 if (typeof customAction === 'string') { 4631 viewType = customAction; 4632 } 4633 calendarApi.zoomTo(dateMarker, viewType); 4634 } 4635 }; 4636 return __assign({ title: formatWithOrdinals(options.navLinkHint, [dateStr, zonedDate], dateStr), 'data-navlink': '' }, (isTabbable 4637 ? createAriaClickAttrs(handleInteraction) 4638 : { onClick: handleInteraction })); 4639 } 4640 return { 'aria-label': dateStr }; 4641 } 4642 4643 var _isRtlScrollbarOnLeft = null; 4644 function getIsRtlScrollbarOnLeft() { 4645 if (_isRtlScrollbarOnLeft === null) { 4646 _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft(); 4647 } 4648 return _isRtlScrollbarOnLeft; 4649 } 4650 function computeIsRtlScrollbarOnLeft() { 4651 var outerEl = document.createElement('div'); 4652 applyStyle(outerEl, { 4653 position: 'absolute', 4654 top: -1000, 4655 left: 0, 4656 border: 0, 4657 padding: 0, 4658 overflow: 'scroll', 4659 direction: 'rtl', 4660 }); 4661 outerEl.innerHTML = '<div></div>'; 4662 document.body.appendChild(outerEl); 4663 var innerEl = outerEl.firstChild; 4664 var res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left; 4665 removeElement(outerEl); 4666 return res; 4667 } 4668 4669 var _scrollbarWidths; 4670 function getScrollbarWidths() { 4671 if (!_scrollbarWidths) { 4672 _scrollbarWidths = computeScrollbarWidths(); 4673 } 4674 return _scrollbarWidths; 4675 } 4676 function computeScrollbarWidths() { 4677 var el = document.createElement('div'); 4678 el.style.overflow = 'scroll'; 4679 el.style.position = 'absolute'; 4680 el.style.top = '-9999px'; 4681 el.style.left = '-9999px'; 4682 document.body.appendChild(el); 4683 var res = computeScrollbarWidthsForEl(el); 4684 document.body.removeChild(el); 4685 return res; 4686 } 4687 // WARNING: will include border 4688 function computeScrollbarWidthsForEl(el) { 4689 return { 4690 x: el.offsetHeight - el.clientHeight, 4691 y: el.offsetWidth - el.clientWidth, 4692 }; 4693 } 4694 4695 function computeEdges(el, getPadding) { 4696 if (getPadding === void 0) { getPadding = false; } 4697 var computedStyle = window.getComputedStyle(el); 4698 var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0; 4699 var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0; 4700 var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0; 4701 var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
4702 var badScrollbarWidths = computeScrollbarWidthsForEl(el); // includes border! 4703 var scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight; 4704 var scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom; 4705 var res = { 4706 borderLeft: borderLeft, 4707 borderRight: borderRight, 4708 borderTop: borderTop, 4709 borderBottom: borderBottom, 4710 scrollbarBottom: scrollbarBottom, 4711 scrollbarLeft: 0, 4712 scrollbarRight: 0, 4713 }; 4714 if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side? 4715 res.scrollbarLeft = scrollbarLeftRight; 4716 } 4717 else { 4718 res.scrollbarRight = scrollbarLeftRight; 4719 } 4720 if (getPadding) { 4721 res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0; 4722 res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0; 4723 res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0; 4724 res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0; 4725 } 4726 return res; 4727 } 4728 function computeInnerRect(el, goWithinPadding, doFromWindowViewport) { 4729 if (goWithinPadding === void 0) { goWithinPadding = false; } 4730 var outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el); 4731 var edges = computeEdges(el, goWithinPadding); 4732 var res = { 4733 left: outerRect.left + edges.borderLeft + edges.scrollbarLeft, 4734 right: outerRect.right - edges.borderRight - edges.scrollbarRight, 4735 top: outerRect.top + edges.borderTop, 4736 bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom, 4737 }; 4738 if (goWithinPadding) { 4739 res.left += edges.paddingLeft; 4740 res.right -= edges.paddingRight; 4741 res.top += edges.paddingTop; 4742 res.bottom -= edges.paddingBottom; 4743 } 4744 return res; 4745 } 4746 function computeRect(el) { 4747 var rect = el.getBoundingClientRect(); 4748 return { 4749 left: rect.left + window.pageXOffset, 4750 top: rect.top + window.pageYOffset, 4751 right: rect.right + window.pageXOffset, 4752 bottom: rect.bottom + window.pageYOffset, 4753 }; 4754 } 4755 function computeClippedClientRect(el) { 4756 var clippingParents = getClippingParents(el); 4757 var rect = el.getBoundingClientRect(); 4758 for (var _i = 0, clippingParents_1 = clippingParents; _i < clippingParents_1.length; _i++) { 4759 var clippingParent = clippingParents_1[_i]; 4760 var intersection = intersectRects(rect, clippingParent.getBoundingClientRect()); 4761 if (intersection) { 4762 rect = intersection; 4763 } 4764 else { 4765 return null; 4766 } 4767 } 4768 return rect; 4769 } 4770 function computeHeightAndMargins(el) { 4771 return el.getBoundingClientRect().height + computeVMargins(el); 4772 } 4773 function computeVMargins(el) { 4774 var computed = window.getComputedStyle(el); 4775 return parseInt(computed.marginTop, 10) + 4776 parseInt(computed.marginBottom, 10); 4777 } 4778 // does not return window 4779 function getClippingParents(el) { 4780 var parents = []; 4781 while (el instanceof HTMLElement) { // will stop when gets to document or null 4782 var computedStyle = window.getComputedStyle(el); 4783 if (computedStyle.position === 'fixed') { 4784 break; 4785 } 4786 if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) { 4787 parents.push(el); 4788 } 4789 el = el.parentNode; 4790 } 4791 return parents; 4792 } 4793 4794 // given a function that resolves a result asynchronously. 4795 // the function can either call passed-in success and failure callbacks, 4796 // or it can return a promise. 4797 // if you need to pass additional params to func, bind them first. 4798 function unpromisify(func, success, failure) { 4799 // guard against success/failure callbacks being called more than once 4800 // and guard against a promise AND callback being used together. 4801 var isResolved = false;
4802 var wrappedSuccess = function () { 4803 if (!isResolved) { 4804 isResolved = true; 4805 success.apply(this, arguments); // eslint-disable-line prefer-rest-params 4806 } 4807 }; 4808 var wrappedFailure = function () { 4809 if (!isResolved) { 4810 isResolved = true; 4811 if (failure) { 4812 failure.apply(this, arguments); // eslint-disable-line prefer-rest-params 4813 } 4814 } 4815 }; 4816 var res = func(wrappedSuccess, wrappedFailure); 4817 if (res && typeof res.then === 'function') { 4818 res.then(wrappedSuccess, wrappedFailure); 4819 } 4820 } 4821 4822 var Emitter = /** @class */ (function () { 4823 function Emitter() { 4824 this.handlers = {}; 4825 this.thisContext = null; 4826 } 4827 Emitter.prototype.setThisContext = function (thisContext) { 4828 this.thisContext = thisContext; 4829 }; 4830 Emitter.prototype.setOptions = function (options) { 4831 this.options = options; 4832 }; 4833 Emitter.prototype.on = function (type, handler) { 4834 addToHash(this.handlers, type, handler); 4835 }; 4836 Emitter.prototype.off = function (type, handler) { 4837 removeFromHash(this.handlers, type, handler); 4838 }; 4839 Emitter.prototype.trigger = function (type) { 4840 var args = []; 4841 for (var _i = 1; _i < arguments.length; _i++) { 4842 args[_i - 1] = arguments[_i]; 4843 } 4844 var attachedHandlers = this.handlers[type] || []; 4845 var optionHandler = this.options && this.options[type]; 4846 var handlers = [].concat(optionHandler || [], attachedHandlers); 4847 for (var _a = 0, handlers_1 = handlers; _a < handlers_1.length; _a++) { 4848 var handler = handlers_1[_a]; 4849 handler.apply(this.thisContext, args); 4850 } 4851 }; 4852 Emitter.prototype.hasHandlers = function (type) { 4853 return Boolean((this.handlers[type] && this.handlers[type].length) || 4854 (this.options && this.options[type])); 4855 }; 4856 return Emitter; 4857 }()); 4858 function addToHash(hash, type, handler) { 4859 (hash[type] || (hash[type] = [])) 4860 .push(handler); 4861 } 4862 function removeFromHash(hash, type, handler) { 4863 if (handler) { 4864 if (hash[type]) { 4865 hash[type] = hash[type].filter(function (func) { return func !== handler; }); 4866 } 4867 } 4868 else { 4869 delete hash[type]; // remove all handler funcs for this type 4870 } 4871 } 4872 4873 /* 4874 Records offset information for a set of elements, relative to an origin element. 4875 Can record the left/right OR the top/bottom OR both. 4876 Provides methods for querying the cache by position. 4877 */ 4878 var PositionCache = /** @class */ (function () { 4879 function PositionCache(originEl, els, isHorizontal, isVertical) { 4880 this.els = els; 4881 var originClientRect = this.originClientRect = originEl.getBoundingClientRect(); // relative to viewport top-left 4882 if (isHorizontal) { 4883 this.buildElHorizontals(originClientRect.left); 4884 } 4885 if (isVertical) { 4886 this.buildElVerticals(originClientRect.top); 4887 } 4888 } 4889 // Populates the left/right internal coordinate arrays 4890 PositionCache.prototype.buildElHorizontals = function (originClientLeft) { 4891 var lefts = []; 4892 var rights = []; 4893 for (var _i = 0, _a = this.els; _i < _a.length; _i++) { 4894 var el = _a[_i]; 4895 var rect = el.getBoundingClientRect(); 4896 lefts.push(rect.left - originClientLeft); 4897 rights.push(rect.right - originClientLeft); 4898 } 4899 this.lefts = lefts; 4900 this.rights = rights; 4901 }; 4902 // Populates the top/bottom internal coordinate arrays 4903 PositionCache.prototype.buildElVerticals = function (originClientTop) { 4904 var tops = []; 4905 var bottoms = []; 4906 for (var _i = 0, _a = this.els; _i < _a.length; _i++) { 4907 var el = _a[_i]; 4908 var rect = el.getBoundingClientRect(); 4909 tops.push(rect.top - originClientTop); 4910 bottoms.push(rect.bottom - originClientTop); 4911 } 4912 this.tops = tops; 4913 this.bottoms = bottoms; 4914 }; 4915 // Given a left offset (from document left), returns the index of the el that it horizontally intersects. 4916 // If no intersection is made, returns undefined. 4917 PositionCache.prototype.leftToIndex = function (leftPosition) { 4918 var _a = this, lefts = _a.lefts, rights = _a.rights; 4919 var len = lefts.length; 4920 var i; 4921 for (i = 0; i < len; i += 1) { 4922 if (leftPosition >= lefts[i] && leftPosition < rights[i]) { 4923 return i; 4924 } 4925 } 4926 return undefined; // TODO: better 4927 }; 4928 // Given a top offset (from document top), returns the index of the el that it vertically intersects. 4929 // If no intersection is made, returns undefined. 4930 PositionCache.prototype.topToIndex = function (topPosition) { 4931 var _a = this, tops = _a.tops, bottoms = _a.bottoms; 4932 var len = tops.length; 4933 var i; 4934 for (i = 0; i < len; i += 1) { 4935 if (topPosition >= tops[i] && topPosition < bottoms[i]) { 4936 return i; 4937 } 4938 } 4939 return undefined; // TODO: better 4940 }; 4941 // Gets the width of the element at the given index 4942 PositionCache.prototype.getWidth = function (leftIndex) { 4943 return this.rights[leftIndex] - this.lefts[leftIndex]; 4944 }; 4945 // Gets the height of the element at the given index 4946 PositionCache.prototype.getHeight = function (topIndex) { 4947 return this.bottoms[topIndex] - this.tops[topIndex]; 4948 }; 4949 return PositionCache; 4950 }()); 4951
4952 /* eslint max-classes-per-file: "off" */ 4953 /* 4954 An object for getting/setting scroll-related information for an element. 4955 Internally, this is done very differently for window versus DOM element, 4956 so this object serves as a common interface. 4957 */ 4958 var ScrollController = /** @class */ (function () { 4959 function ScrollController() { 4960 } 4961 ScrollController.prototype.getMaxScrollTop = function () { 4962 return this.getScrollHeight() - this.getClientHeight(); 4963 }; 4964 ScrollController.prototype.getMaxScrollLeft = function () { 4965 return this.getScrollWidth() - this.getClientWidth(); 4966 }; 4967 ScrollController.prototype.canScrollVertically = function () { 4968 return this.getMaxScrollTop() > 0; 4969 }; 4970 ScrollController.prototype.canScrollHorizontally = function () { 4971 return this.getMaxScrollLeft() > 0; 4972 }; 4973 ScrollController.prototype.canScrollUp = function () { 4974 return this.getScrollTop() > 0; 4975 }; 4976 ScrollController.prototype.canScrollDown = function () { 4977 return this.getScrollTop() < this.getMaxScrollTop(); 4978 }; 4979 ScrollController.prototype.canScrollLeft = function () { 4980 return this.getScrollLeft() > 0; 4981 }; 4982 ScrollController.prototype.canScrollRight = function () { 4983 return this.getScrollLeft() < this.getMaxScrollLeft(); 4984 }; 4985 return ScrollController; 4986 }()); 4987 var ElementScrollController = /** @class */ (function (_super) { 4988 __extends(ElementScrollController, _super); 4989 function ElementScrollController(el) { 4990 var _this = _super.call(this) || this; 4991 _this.el = el; 4992 return _this; 4993 } 4994 ElementScrollController.prototype.getScrollTop = function () { 4995 return this.el.scrollTop; 4996 }; 4997 ElementScrollController.prototype.getScrollLeft = function () { 4998 return this.el.scrollLeft; 4999 }; 5000 ElementScrollController.prototype.setScrollTop = function (top) { 5001 this.el.scrollTop = top; 5002 }; 5003 ElementScrollController.prototype.setScrollLeft = function (left) { 5004 this.el.scrollLeft = left; 5005 }; 5006 ElementScrollController.prototype.getScrollWidth = function () { 5007 return this.el.scrollWidth; 5008 }; 5009 ElementScrollController.prototype.getScrollHeight = function () { 5010 return this.el.scrollHeight; 5011 }; 5012 ElementScrollController.prototype.getClientHeight = function () { 5013 return this.el.clientHeight; 5014 }; 5015 ElementScrollController.prototype.getClientWidth = function () { 5016 return this.el.clientWidth; 5017 }; 5018 return ElementScrollController; 5019 }(ScrollController)); 5020 var WindowScrollController = /** @class */ (function (_super) { 5021 __extends(WindowScrollController, _super); 5022 function WindowScrollController() { 5023 return _super !== null && _super.apply(this, arguments) || this; 5024 } 5025 WindowScrollController.prototype.getScrollTop = function () { 5026 return window.pageYOffset; 5027 }; 5028 WindowScrollController.prototype.getScrollLeft = function () { 5029 return window.pageXOffset; 5030 }; 5031 WindowScrollController.prototype.setScrollTop = function (n) { 5032 window.scroll(window.pageXOffset, n); 5033 }; 5034 WindowScrollController.prototype.setScrollLeft = function (n) { 5035 window.scroll(n, window.pageYOffset); 5036 }; 5037 WindowScrollController.prototype.getScrollWidth = function () { 5038 return document.documentElement.scrollWidth; 5039 }; 5040 WindowScrollController.prototype.getScrollHeight = function () { 5041 return document.documentElement.scrollHeight; 5042 }; 5043 WindowScrollController.prototype.getClientHeight = function () { 5044 return document.documentElement.clientHeight; 5045 }; 5046 WindowScrollController.prototype.getClientWidth = function () { 5047 return document.documentElement.clientWidth; 5048 }; 5049 return WindowScrollController; 5050 }(ScrollController)); 5051 5052 var Theme = /** @class */ (function () { 5053 function Theme(calendarOptions) { 5054 if (this.iconOverrideOption) { 5055 this.setIconOverride(calendarOptions[this.iconOverrideOption]); 5056 } 5057 } 5058 Theme.prototype.setIconOverride = function (iconOverrideHash) { 5059 var iconClassesCopy; 5060 var buttonName; 5061 if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object 5062 iconClassesCopy = __assign({}, this.iconClasses); 5063 for (buttonName in iconOverrideHash) { 5064 iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]); 5065 } 5066 this.iconClasses = iconClassesCopy; 5067 } 5068 else if (iconOverrideHash === false) { 5069 this.iconClasses = {}; 5070 } 5071 }; 5072 Theme.prototype.applyIconOverridePrefix = function (className) { 5073 var prefix = this.iconOverridePrefix; 5074 if (prefix && className.indexOf(prefix) !== 0) { // if not already present 5075 className = prefix + className; 5076 } 5077 return className; 5078 }; 5079 Theme.prototype.getClass = function (key) { 5080 return this.classes[key] || ''; 5081 }; 5082 Theme.prototype.getIconClass = function (buttonName, isRtl) { 5083 var className; 5084 if (isRtl && this.rtlIconClasses) { 5085 className = this.rtlIconClasses[buttonName] || this.iconClasses[buttonName]; 5086 } 5087 else { 5088 className = this.iconClasses[buttonName]; 5089 } 5090 if (className) { 5091 return this.baseIconClass + " " + className; 5092 } 5093 return ''; 5094 }; 5095 Theme.prototype.getCustomButtonIconClass = function (customButtonProps) { 5096 var className; 5097 if (this.iconOverrideCustomButtonOption) { 5098 className = customButtonProps[this.iconOverrideCustomButtonOption]; 5099 if (className) { 5100 return this.baseIconClass + " " + this.applyIconOverridePrefix(className); 5101 } 5102 } 5103 return ''; 5104 }; 5105 return Theme; 5106 }()); 5107 Theme.prototype.classes = {}; 5108 Theme.prototype.iconClasses = {}; 5109 Theme.prototype.baseIconClass = ''; 5110 Theme.prototype.iconOverridePrefix = ''; 5111 5112 /// <reference types="@fullcalendar/core-preact" /> 5113 if (typeof FullCalendarVDom === 'undefined') { 5114 throw new Error('Please import the top-level fullcalendar lib before attempting to import a plugin.'); 5115 } 5116 var Component = FullCalendarVDom.Component; 5117 var createElement = FullCalendarVDom.createElement; 5118 var render = FullCalendarVDom.render; 5119 var createRef = FullCalendarVDom.createRef; 5120 var Fragment = FullCalendarVDom.Fragment; 5121 var createContext = FullCalendarVDom.createContext; 5122 var createPortal = FullCalendarVDom.createPortal; 5123 var flushToDom = FullCalendarVDom.flushToDom; 5124 var unmountComponentAtNode = FullCalendarVDom.unmountComponentAtNode; 5125 /* eslint-enable */ 5126 5127 var ScrollResponder = /** @class */ (function () { 5128 function ScrollResponder(execFunc, emitter, scrollTime, scrollTimeReset) { 5129 var _this = this; 5130 this.execFunc = execFunc; 5131 this.emitter = emitter; 5132 this.scrollTime = scrollTime; 5133 this.scrollTimeReset = scrollTimeReset; 5134 this.handleScrollRequest = function (request) { 5135 _this.queuedRequest = __assign({}, _this.queuedRequest || {}, request); 5136 _this.drain(); 5137 }; 5138 emitter.on('_scrollRequest', this.handleScrollRequest); 5139 this.fireInitialScroll(); 5140 } 5141 ScrollResponder.prototype.detach = function () { 5142 this.emitter.off('_scrollRequest', this.handleScrollRequest); 5143 }; 5144 ScrollResponder.prototype.update = function (isDatesNew) { 5145 if (isDatesNew && this.scrollTimeReset) { 5146 this.fireInitialScroll(); // will drain 5147 } 5148 else { 5149 this.drain(); 5150 } 5151 }; 5152 ScrollResponder.prototype.fireInitialScroll = function () { 5153 this.handleScrollRequest({ 5154 time: this.scrollTime, 5155 }); 5156 };
5157 ScrollResponder.prototype.drain = function () { 5158 if (this.queuedRequest && this.execFunc(this.queuedRequest)) { 5159 this.queuedRequest = null; 5160 } 5161 }; 5162 return ScrollResponder; 5163 }()); 5164 5165 var ViewContextType = createContext({}); // for Components 5166 function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) { 5167 return { 5168 dateEnv: dateEnv, 5169 options: viewOptions, 5170 pluginHooks: pluginHooks, 5171 emitter: emitter, 5172 dispatch: dispatch, 5173 getCurrentData: getCurrentData, 5174 calendarApi: calendarApi, 5175 viewSpec: viewSpec, 5176 viewApi: viewApi, 5177 dateProfileGenerator: dateProfileGenerator, 5178 theme: theme, 5179 isRtl: viewOptions.direction === 'rtl', 5180 addResizeHandler: function (handler) { 5181 emitter.on('_resize', handler); 5182 }, 5183 removeResizeHandler: function (handler) { 5184 emitter.off('_resize', handler); 5185 }, 5186 createScrollResponder: function (execFunc) { 5187 return new ScrollResponder(execFunc, emitter, createDuration(viewOptions.scrollTime), viewOptions.scrollTimeReset); 5188 }, 5189 registerInteractiveComponent: registerInteractiveComponent, 5190 unregisterInteractiveComponent: unregisterInteractiveComponent, 5191 }; 5192 } 5193 5194 /* eslint max-classes-per-file: off */ 5195 var PureComponent = /** @class */ (function (_super) { 5196 __extends(PureComponent, _super); 5197 function PureComponent() { 5198 return _super !== null && _super.apply(this, arguments) || this; 5199 } 5200 PureComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) { 5201 if (this.debug) { 5202 // eslint-disable-next-line no-console 5203 console.log(getUnequalProps(nextProps, this.props), getUnequalProps(nextState, this.state)); 5204 } 5205 return !compareObjs(this.props, nextProps, this.propEquality) || 5206 !compareObjs(this.state, nextState, this.stateEquality); 5207 }; 5208 PureComponent.addPropsEquality = addPropsEquality; 5209 PureComponent.addStateEquality = addStateEquality; 5210 PureComponent.contextType = ViewContextType; 5211 return PureComponent; 5212 }(Component)); 5213 PureComponent.prototype.propEquality = {}; 5214 PureComponent.prototype.stateEquality = {}; 5215 var BaseComponent = /** @class */ (function (_super) { 5216 __extends(BaseComponent, _super); 5217 function BaseComponent() { 5218 return _super !== null && _super.apply(this, arguments) || this; 5219 } 5220 BaseComponent.contextType = ViewContextType; 5221 return BaseComponent; 5222 }(PureComponent)); 5223 function addPropsEquality(propEquality) { 5224 var hash = Object.create(this.prototype.propEquality); 5225 __assign(hash, propEquality); 5226 this.prototype.propEquality = hash; 5227 } 5228 function addStateEquality(stateEquality) { 5229 var hash = Object.create(this.prototype.stateEquality); 5230 __assign(hash, stateEquality); 5231 this.prototype.stateEquality = hash; 5232 } 5233 // use other one 5234 function setRef(ref, current) { 5235 if (typeof ref === 'function') { 5236 ref(current); 5237 } 5238 else if (ref) { 5239 // see https://github.com/facebook/react/issues/13029 5240 ref.current = current; 5241 } 5242 } 5243 5244 /* 5245 an INTERACTABLE date component 5246 5247 PURPOSES: 5248 - hook up to fg, fill, and mirror renderers 5249 - interface for dragging and hits 5250 */ 5251 var DateComponent = /** @class */ (function (_super) { 5252 __extends(DateComponent, _super); 5253 function DateComponent() { 5254 var _this = _super !== null && _super.apply(this, arguments) || this; 5255 _this.uid = guid(); 5256 return _this; 5257 } 5258 // Hit System 5259 // ----------------------------------------------------------------------------------------------------------------- 5260 DateComponent.prototype.prepareHits = function () { 5261 }; 5262 DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) { 5263 return null; // this should be abstract 5264 }; 5265 // Pointer Interaction Utils 5266 // ----------------------------------------------------------------------------------------------------------------- 5267 DateComponent.prototype.isValidSegDownEl = function (el) { 5268 return !this.props.eventDrag && // HACK 5269 !this.props.eventResize && // HACK 5270 !elementClosest(el, '.fc-event-mirror'); 5271 }; 5272 DateComponent.prototype.isValidDateDownEl = function (el) { 5273 return !elementClosest(el, '.fc-event:not(.fc-bg-event)') && 5274 !elementClosest(el, '.fc-more-link') && // a "more.." link 5275 !elementClosest(el, 'a[data-navlink]') && // a clickable nav link 5276 !elementClosest(el, '.fc-popover'); // hack 5277 }; 5278 return DateComponent; 5279 }(BaseComponent)); 5280 5281 // TODO: easier way to add new hooks? need to update a million things 5282 function createPlugin(input) { 5283 return { 5284 id: guid(), 5285 deps: input.deps || [], 5286 reducers: input.reducers || [], 5287 isLoadingFuncs: input.isLoadingFuncs || [], 5288 contextInit: [].concat(input.contextInit || []), 5289 eventRefiners: input.eventRefiners || {}, 5290 eventDefMemberAdders: input.eventDefMemberAdders || [], 5291 eventSourceRefiners: input.eventSourceRefiners || {}, 5292 isDraggableTransformers: input.isDraggableTransformers || [], 5293 eventDragMutationMassagers: input.eventDragMutationMassagers || [], 5294 eventDefMutationAppliers: input.eventDefMutationAppliers || [], 5295 dateSelectionTransformers: input.dateSelectionTransformers || [], 5296 datePointTransforms: input.datePointTransforms || [], 5297 dateSpanTransforms: input.dateSpanTransforms || [], 5298 views: input.views || {}, 5299 viewPropsTransformers: input.viewPropsTransformers || [], 5300 isPropsValid: input.isPropsValid || null, 5301 externalDefTransforms: input.externalDefTransforms || [], 5302 viewContainerAppends: input.viewContainerAppends || [], 5303 eventDropTransformers: input.eventDropTransformers || [], 5304 componentInteractions: input.componentInteractions || [], 5305 calendarInteractions: input.calendarInteractions || [],
5306 themeClasses: input.themeClasses || {}, 5307 eventSourceDefs: input.eventSourceDefs || [], 5308 cmdFormatter: input.cmdFormatter, 5309 recurringTypes: input.recurringTypes || [], 5310 namedTimeZonedImpl: input.namedTimeZonedImpl, 5311 initialView: input.initialView || '', 5312 elementDraggingImpl: input.elementDraggingImpl, 5313 optionChangeHandlers: input.optionChangeHandlers || {}, 5314 scrollGridImpl: input.scrollGridImpl || null, 5315 contentTypeHandlers: input.contentTypeHandlers || {}, 5316 listenerRefiners: input.listenerRefiners || {}, 5317 optionRefiners: input.optionRefiners || {}, 5318 propSetHandlers: input.propSetHandlers || {}, 5319 }; 5320 } 5321 function buildPluginHooks(pluginDefs, globalDefs) { 5322 var isAdded = {}; 5323 var hooks = { 5324 reducers: [], 5325 isLoadingFuncs: [], 5326 contextInit: [], 5327 eventRefiners: {}, 5328 eventDefMemberAdders: [], 5329 eventSourceRefiners: {}, 5330 isDraggableTransformers: [], 5331 eventDragMutationMassagers: [], 5332 eventDefMutationAppliers: [], 5333 dateSelectionTransformers: [], 5334 datePointTransforms: [], 5335 dateSpanTransforms: [], 5336 views: {}, 5337 viewPropsTransformers: [], 5338 isPropsValid: null, 5339 externalDefTransforms: [], 5340 viewContainerAppends: [], 5341 eventDropTransformers: [], 5342 componentInteractions: [], 5343 calendarInteractions: [], 5344 themeClasses: {}, 5345 eventSourceDefs: [], 5346 cmdFormatter: null, 5347 recurringTypes: [], 5348 namedTimeZonedImpl: null, 5349 initialView: '', 5350 elementDraggingImpl: null, 5351 optionChangeHandlers: {}, 5352 scrollGridImpl: null, 5353 contentTypeHandlers: {}, 5354 listenerRefiners: {}, 5355 optionRefiners: {}, 5356 propSetHandlers: {}, 5357 }; 5358 function addDefs(defs) { 5359 for (var _i = 0, defs_1 = defs; _i < defs_1.length; _i++) { 5360 var def = defs_1[_i]; 5361 if (!isAdded[def.id]) { 5362 isAdded[def.id] = true; 5363 addDefs(def.deps); 5364 hooks = combineHooks(hooks, def); 5365 } 5366 } 5367 } 5368 if (pluginDefs) { 5369 addDefs(pluginDefs); 5370 } 5371 addDefs(globalDefs); 5372 return hooks; 5373 } 5374 function buildBuildPluginHooks() { 5375 var currentOverrideDefs = []; 5376 var currentGlobalDefs = []; 5377 var currentHooks; 5378 return function (overrideDefs, globalDefs) { 5379 if (!currentHooks || !isArraysEqual(overrideDefs, currentOverrideDefs) || !isArraysEqual(globalDefs, currentGlobalDefs)) { 5380 currentHooks = buildPluginHooks(overrideDefs, globalDefs); 5381 } 5382 currentOverrideDefs = overrideDefs; 5383 currentGlobalDefs = globalDefs; 5384 return currentHooks; 5385 }; 5386 } 5387 function combineHooks(hooks0, hooks1) { 5388 return { 5389 reducers: hooks0.reducers.concat(hooks1.reducers), 5390 isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs), 5391 contextInit: hooks0.contextInit.concat(hooks1.contextInit), 5392 eventRefiners: __assign(__assign({}, hooks0.eventRefiners), hooks1.eventRefiners), 5393 eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders), 5394 eventSourceRefiners: __assign(__assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners), 5395 isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers), 5396 eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers), 5397 eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers), 5398 dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers), 5399 datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms), 5400 dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms), 5401 views: __assign(__assign({}, hooks0.views), hooks1.views), 5402 viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers), 5403 isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid, 5404 externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms), 5405 viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends), 5406 eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers), 5407 calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions), 5408 componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
5409 themeClasses: __assign(__assign({}, hooks0.themeClasses), hooks1.themeClasses), 5410 eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs), 5411 cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter, 5412 recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes), 5413 namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl, 5414 initialView: hooks0.initialView || hooks1.initialView, 5415 elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl, 5416 optionChangeHandlers: __assign(__assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers), 5417 scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl, 5418 contentTypeHandlers: __assign(__assign({}, hooks0.contentTypeHandlers), hooks1.contentTypeHandlers), 5419 listenerRefiners: __assign(__assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners), 5420 optionRefiners: __assign(__assign({}, hooks0.optionRefiners), hooks1.optionRefiners), 5421 propSetHandlers: __assign(__assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers), 5422 }; 5423 } 5424 5425 var StandardTheme = /** @class */ (function (_super) { 5426 __extends(StandardTheme, _super); 5427 function StandardTheme() { 5428 return _super !== null && _super.apply(this, arguments) || this; 5429 } 5430 return StandardTheme; 5431 }(Theme)); 5432 StandardTheme.prototype.classes = { 5433 root: 'fc-theme-standard', 5434 tableCellShaded: 'fc-cell-shaded', 5435 buttonGroup: 'fc-button-group', 5436 button: 'fc-button fc-button-primary', 5437 buttonActive: 'fc-button-active', 5438 }; 5439 StandardTheme.prototype.baseIconClass = 'fc-icon'; 5440 StandardTheme.prototype.iconClasses = { 5441 close: 'fc-icon-x', 5442 prev: 'fc-icon-chevron-left', 5443 next: 'fc-icon-chevron-right', 5444 prevYear: 'fc-icon-chevrons-left', 5445 nextYear: 'fc-icon-chevrons-right', 5446 }; 5447 StandardTheme.prototype.rtlIconClasses = { 5448 prev: 'fc-icon-chevron-right', 5449 next: 'fc-icon-chevron-left', 5450 prevYear: 'fc-icon-chevrons-right', 5451 nextYear: 'fc-icon-chevrons-left', 5452 }; 5453 StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly 5454 StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon'; 5455 StandardTheme.prototype.iconOverridePrefix = 'fc-icon-'; 5456 5457 function compileViewDefs(defaultConfigs, overrideConfigs) { 5458 var hash = {}; 5459 var viewType; 5460 for (viewType in defaultConfigs) { 5461 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5462 } 5463 for (viewType in overrideConfigs) { 5464 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5465 } 5466 return hash; 5467 } 5468 function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 5469 if (hash[viewType]) { 5470 return hash[viewType]; 5471 } 5472 var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5473 if (viewDef) { 5474 hash[viewType] = viewDef; 5475 } 5476 return viewDef; 5477 } 5478 function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 5479 var defaultConfig = defaultConfigs[viewType]; 5480 var overrideConfig = overrideConfigs[viewType]; 5481 var queryProp = function (name) { return ((defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] : 5482 ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null)); }; 5483 var theComponent = queryProp('component'); 5484 var superType = queryProp('superType'); 5485 var superDef = null; 5486 if (superType) { 5487 if (superType === viewType) { 5488 throw new Error('Can\'t have a custom view type that references itself'); 5489 } 5490 superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs); 5491 } 5492 if (!theComponent && superDef) { 5493 theComponent = superDef.component; 5494 } 5495 if (!theComponent) { 5496 return null; // don't throw a warning, might be settings for a single-unit view 5497 } 5498 return { 5499 type: viewType, 5500 component: theComponent, 5501 defaults: __assign(__assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})), 5502 overrides: __assign(__assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {})), 5503 }; 5504 } 5505
5506 /* eslint max-classes-per-file: off */ 5507 // NOTE: in JSX, you should always use this class with <HookProps> arg. otherwise, will default to any??? 5508 var RenderHook = /** @class */ (function (_super) { 5509 __extends(RenderHook, _super); 5510 function RenderHook() { 5511 var _this = _super !== null && _super.apply(this, arguments) || this; 5512 _this.rootElRef = createRef(); 5513 _this.handleRootEl = function (el) { 5514 setRef(_this.rootElRef, el); 5515 if (_this.props.elRef) { 5516 setRef(_this.props.elRef, el); 5517 } 5518 }; 5519 return _this; 5520 } 5521 RenderHook.prototype.render = function () { 5522 var _this = this; 5523 var props = this.props; 5524 var hookProps = props.hookProps; 5525 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); })); })); 5526 }; 5527 return RenderHook; 5528 }(BaseComponent)); 5529 // TODO: rename to be about function, not default. use in above type 5530 // for forcing rerender of components that use the ContentHook 5531 var CustomContentRenderContext = createContext(0); 5532 function ContentHook(props) { 5533 return (createElement(CustomContentRenderContext.Consumer, null, function (renderId) { return (createElement(ContentHookInner, __assign({ renderId: renderId }, props))); })); 5534 } 5535 var ContentHookInner = /** @class */ (function (_super) { 5536 __extends(ContentHookInner, _super); 5537 function ContentHookInner() { 5538 var _this = _super !== null && _super.apply(this, arguments) || this; 5539 _this.innerElRef = createRef(); 5540 return _this; 5541 } 5542 ContentHookInner.prototype.render = function () { 5543 return this.props.children(this.innerElRef, this.renderInnerContent()); 5544 }; 5545 ContentHookInner.prototype.componentDidMount = function () { 5546 this.updateCustomContent(); 5547 }; 5548 ContentHookInner.prototype.componentDidUpdate = function () { 5549 this.updateCustomContent(); 5550 }; 5551 ContentHookInner.prototype.componentWillUnmount = function () { 5552 if (this.customContentInfo && this.customContentInfo.destroy) { 5553 this.customContentInfo.destroy(); 5554 } 5555 }; 5556 ContentHookInner.prototype.renderInnerContent = function () { 5557 var customContentInfo = this.customContentInfo; // only populated if using non-[p]react node(s) 5558 var innerContent = this.getInnerContent(); 5559 var meta = this.getContentMeta(innerContent); 5560 // initial run, or content-type changing? (from vue -> react for example) 5561 if (!customContentInfo || customContentInfo.contentKey !== meta.contentKey) { 5562 // clearing old value 5563 if (customContentInfo) { 5564 if (customContentInfo.destroy) { 5565 customContentInfo.destroy(); 5566 } 5567 customContentInfo = this.customContentInfo = null; 5568 } 5569 // assigning new value 5570 if (meta.contentKey) { 5571 customContentInfo = this.customContentInfo = __assign({ contentKey: meta.contentKey, contentVal: innerContent[meta.contentKey] }, meta.buildLifecycleFuncs()); 5572 } 5573 // updating 5574 } 5575 else if (customContentInfo) { 5576 customContentInfo.contentVal = innerContent[meta.contentKey]; 5577 } 5578 return customContentInfo 5579 ? [] // signal that something was specified 5580 : innerContent; // assume a [p]react vdom node. use it 5581 }; 5582 ContentHookInner.prototype.getInnerContent = function () { 5583 var props = this.props; 5584 var innerContent = normalizeContent(props.content, props.hookProps); 5585 if (innerContent === undefined) { // use the default 5586 innerContent = normalizeContent(props.defaultContent, props.hookProps); 5587 } 5588 return innerContent == null ? null : innerContent; // convert undefined to null (better for React) 5589 }; 5590 ContentHookInner.prototype.getContentMeta = function (innerContent) { 5591 var contentTypeHandlers = this.context.pluginHooks.contentTypeHandlers; 5592 var contentKey = ''; 5593 var buildLifecycleFuncs = null; 5594 if (innerContent) { // allowed to be null, for convenience to caller 5595 for (var searchKey in contentTypeHandlers) { 5596 if (innerContent[searchKey] !== undefined) { 5597 contentKey = searchKey; 5598 buildLifecycleFuncs = contentTypeHandlers[searchKey]; 5599 break; 5600 } 5601 } 5602 } 5603 return { contentKey: contentKey, buildLifecycleFuncs: buildLifecycleFuncs }; 5604 }; 5605 ContentHookInner.prototype.updateCustomContent = function () { 5606 if (this.customContentInfo) { // for non-[p]react 5607 this.customContentInfo.render(this.innerElRef.current || this.props.backupElRef.current, // the element to render into 5608 this.customContentInfo.contentVal); 5609 } 5610 }; 5611 return ContentHookInner; 5612 }(BaseComponent)); 5613 var MountHook = /** @class */ (function (_super) { 5614 __extends(MountHook, _super); 5615 function MountHook() { 5616 var _this = _super !== null && _super.apply(this, arguments) || this; 5617 _this.handleRootEl = function (rootEl) { 5618 _this.rootEl = rootEl; 5619 if (_this.props.elRef) { 5620 setRef(_this.props.elRef, rootEl); 5621 } 5622 }; 5623 return _this; 5624 } 5625 MountHook.prototype.render = function () { 5626 return this.props.children(this.handleRootEl); 5627 }; 5628 MountHook.prototype.componentDidMount = function () { 5629 var callback = this.props.didMount; 5630 if (callback) { 5631 callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl })); 5632 } 5633 }; 5634 MountHook.prototype.componentWillUnmount = function () { 5635 var callback = this.props.willUnmount; 5636 if (callback) { 5637 callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl })); 5638 } 5639 }; 5640 return MountHook; 5641 }(BaseComponent)); 5642 function buildClassNameNormalizer() { 5643 var currentGenerator; 5644 var currentHookProps; 5645 var currentClassNames = []; 5646 return function (generator, hookProps) { 5647 if (!currentHookProps || !isPropsEqual(currentHookProps, hookProps) || generator !== currentGenerator) { 5648 currentGenerator = generator; 5649 currentHookProps = hookProps; 5650 currentClassNames = normalizeClassNames(generator, hookProps); 5651 } 5652 return currentClassNames; 5653 }; 5654 } 5655 function normalizeClassNames(classNames, hookProps) { 5656 if (typeof classNames === 'function') { 5657 classNames = classNames(hookProps); 5658 } 5659 return parseClassNames(classNames); 5660 } 5661 function normalizeContent(input, hookProps) { 5662 if (typeof input === 'function') { 5663 return input(hookProps, createElement); // give the function the vdom-creation func 5664 } 5665 return input; 5666 } 5667 5668 var ViewRoot = /** @class */ (function (_super) { 5669 __extends(ViewRoot, _super); 5670 function ViewRoot() { 5671 var _this = _super !== null && _super.apply(this, arguments) || this; 5672 _this.normalizeClassNames = buildClassNameNormalizer(); 5673 return _this; 5674 } 5675 ViewRoot.prototype.render = function () { 5676 var _a = this, props = _a.props, context = _a.context; 5677 var options = context.options; 5678 var hookProps = { view: context.viewApi }; 5679 var customClassNames = this.normalizeClassNames(options.viewClassNames, hookProps); 5680 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)); })); 5681 }; 5682 return ViewRoot; 5683 }(BaseComponent)); 5684 5685 function parseViewConfigs(inputs) { 5686 return mapHash(inputs, parseViewConfig); 5687 } 5688 function parseViewConfig(input) { 5689 var rawOptions = typeof input === 'function' ? 5690 { component: input } : 5691 input; 5692 var component = rawOptions.component; 5693 if (rawOptions.content) { 5694 component = createViewHookComponent(rawOptions); 5695 // TODO: remove content/classNames/didMount/etc from options? 5696 } 5697 return { 5698 superType: rawOptions.type, 5699 component: component, 5700 rawOptions: rawOptions, 5701 }; 5702 } 5703 function createViewHookComponent(options) { 5704 return function (viewProps) { return (createElement(ViewContextType.Consumer, null, function (context) { return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (viewElRef, viewClassNames) { 5705 var hookProps = __assign(__assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold }); 5706 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
5706oncat(customClassNames).join(' '), ref: rootElRef }, innerContent)); })); 5707 })); })); }; 5708 } 5709 5710 function buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) { 5711 var defaultConfigs = parseViewConfigs(defaultInputs); 5712 var overrideConfigs = parseViewConfigs(optionOverrides.views); 5713 var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs); 5714 return mapHash(viewDefs, function (viewDef) { return buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults); }); 5715 } 5716 function buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) { 5717 var durationInput = viewDef.overrides.duration || 5718 viewDef.defaults.duration || 5719 dynamicOptionOverrides.duration || 5720 optionOverrides.duration; 5721 var duration = null; 5722 var durationUnit = ''; 5723 var singleUnit = ''; 5724 var singleUnitOverrides = {}; 5725 if (durationInput) { 5726 duration = createDurationCached(durationInput); 5727 if (duration) { // valid? 5728 var denom = greatestDurationDenominator(duration); 5729 durationUnit = denom.unit; 5730 if (denom.value === 1) { 5731 singleUnit = durationUnit; 5732 singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {}; 5733 } 5734 } 5735 } 5736 var queryButtonText = function (optionsSubset) { 5737 var buttonTextMap = optionsSubset.buttonText || {}; 5738 var buttonTextKey = viewDef.defaults.buttonTextKey; 5739 if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) { 5740 return buttonTextMap[buttonTextKey]; 5741 } 5742 if (buttonTextMap[viewDef.type] != null) { 5743 return buttonTextMap[viewDef.type]; 5744 } 5745 if (buttonTextMap[singleUnit] != null) { 5746 return buttonTextMap[singleUnit]; 5747 } 5748 return null; 5749 }; 5750 var queryButtonTitle = function (optionsSubset) { 5751 var buttonHints = optionsSubset.buttonHints || {}; 5752 var buttonKey = viewDef.defaults.buttonTextKey; // use same key as text 5753 if (buttonKey != null && buttonHints[buttonKey] != null) { 5754 return buttonHints[buttonKey]; 5755 } 5756 if (buttonHints[viewDef.type] != null) { 5757 return buttonHints[viewDef.type]; 5758 } 5759 if (buttonHints[singleUnit] != null) { 5760 return buttonHints[singleUnit]; 5761 } 5762 return null; 5763 }; 5764 return { 5765 type: viewDef.type, 5766 component: viewDef.component, 5767 duration: duration, 5768 durationUnit: durationUnit, 5769 singleUnit: singleUnit, 5770 optionDefaults: viewDef.defaults, 5771 optionOverrides: __assign(__assign({}, singleUnitOverrides), viewDef.overrides), 5772 buttonTextOverride: queryButtonText(dynamicOptionOverrides) || 5773 queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence 5774 viewDef.overrides.buttonText, 5775 buttonTextDefault: queryButtonText(localeDefaults) || 5776 viewDef.defaults.buttonText || 5777 queryButtonText(BASE_OPTION_DEFAULTS) || 5778 viewDef.type, 5779 // not DRY 5780 buttonTitleOverride: queryButtonTitle(dynamicOptionOverrides) || 5781 queryButtonTitle(optionOverrides) || 5782 viewDef.overrides.buttonHint, 5783 buttonTitleDefault: queryButtonTitle(localeDefaults) || 5784 viewDef.defaults.buttonHint || 5785 queryButtonTitle(BASE_OPTION_DEFAULTS), 5786 // will eventually fall back to buttonText 5787 }; 5788 } 5789 // hack to get memoization working 5790 var durationInputMap = {}; 5791 function createDurationCached(durationInput) { 5792 var json = JSON.stringify(durationInput); 5793 var res = durationInputMap[json]; 5794 if (res === undefined) { 5795 res = createDuration(durationInput); 5796 durationInputMap[json] = res; 5797 } 5798 return res; 5799 } 5800 5801 var DateProfileGenerator = /** @class */ (function () { 5802 function DateProfileGenerator(props) { 5803 this.props = props; 5804 this.nowDate = getNow(props.nowInput, props.dateEnv); 5805 this.initHiddenDays(); 5806 } 5807 /* Date Range Computation 5808 ------------------------------------------------------------------------------------------------------------------*/ 5809 // Builds a structure with info about what the dates/ranges will be for the "prev" view. 5810 DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate, forceToValid) { 5811 var dateEnv = this.props.dateEnv; 5812 var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 5813 currentDateProfile.dateIncrement); 5814 return this.build(prevDate, -1, forceToValid); 5815 }; 5816 // Builds a structure with info about what the dates/ranges will be for the "next" view. 5817 DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate, forceToValid) { 5818 var dateEnv = this.props.dateEnv; 5819 var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 5820 currentDateProfile.dateIncrement); 5821 return this.build(nextDate, 1, forceToValid); 5822 }; 5823 // Builds a structure holding dates/ranges for rendering around the given date. 5824 // Optional direction param indicates whether the date is being incremented/decremented 5825 // from its previous value. decremented = -1, incremented = 1 (default). 5826 DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) { 5827 if (forceToValid === void 0) { forceToValid = true; } 5828 var props = this.props;
5829 var validRange; 5830 var currentInfo; 5831 var isRangeAllDay; 5832 var renderRange; 5833 var activeRange; 5834 var isValid; 5835 validRange = this.buildValidRange(); 5836 validRange = this.trimHiddenDays(validRange); 5837 if (forceToValid) { 5838 currentDate = constrainMarkerToRange(currentDate, validRange); 5839 } 5840 currentInfo = this.buildCurrentRangeInfo(currentDate, direction); 5841 isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit); 5842 renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay); 5843 renderRange = this.trimHiddenDays(renderRange); 5844 activeRange = renderRange; 5845 if (!props.showNonCurrentDates) { 5846 activeRange = intersectRanges(activeRange, currentInfo.range); 5847 } 5848 activeRange = this.adjustActiveRange(activeRange); 5849 activeRange = intersectRanges(activeRange, validRange); // might return null 5850 // it's invalid if the originally requested date is not contained, 5851 // or if the range is completely outside of the valid range. 5852 isValid = rangesIntersect(currentInfo.range, validRange); 5853 return { 5854 // constraint for where prev/next operations can go and where events can be dragged/resized to. 5855 // an object with optional start and end properties. 5856 validRange: validRange, 5857 // range the view is formally responsible for. 5858 // for example, a month view might have 1st-31st, excluding padded dates 5859 currentRange: currentInfo.range, 5860 // name of largest unit being displayed, like "month" or "week" 5861 currentRangeUnit: currentInfo.unit, 5862 isRangeAllDay: isRangeAllDay, 5863 // dates that display events and accept drag-n-drop 5864 // will be `null` if no dates accept events 5865 activeRange: activeRange, 5866 // date range with a rendered skeleton 5867 // includes not-active days that need some sort of DOM 5868 renderRange: renderRange, 5869 // Duration object that denotes the first visible time of any given day 5870 slotMinTime: props.slotMinTime, 5871 // Duration object that denotes the exclusive visible end time of any given day 5872 slotMaxTime: props.slotMaxTime, 5873 isValid: isValid, 5874 // how far the current date will move for a prev/next operation 5875 dateIncrement: this.buildDateIncrement(currentInfo.duration), 5876 // pass a fallback (might be null) ^ 5877 }; 5878 }; 5879 // Builds an object with optional start/end properties. 5880 // Indicates the minimum/maximum dates to display. 5881 // not responsible for trimming hidden days. 5882 DateProfileGenerator.prototype.buildValidRange = function () { 5883 var input = this.props.validRangeInput; 5884 var simpleInput = typeof input === 'function' 5885 ? input.call(this.props.calendarApi, this.nowDate) 5886 : input; 5887 return this.refineRange(simpleInput) || 5888 { start: null, end: null }; // completely open-ended 5889 }; 5890 // Builds a structure with info about the "current" range, the range that is 5891 // highlighted as being the current month for example. 5892 // See build() for a description of `direction`. 5893 // Guaranteed to have `range` and `unit` properties. `duration` is optional. 5894 DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) { 5895 var props = this.props; 5896 var duration = null; 5897 var unit = null; 5898 var range = null; 5899 var dayCount; 5900 if (props.duration) { 5901 duration = props.duration; 5902 unit = props.durationUnit; 5903 range = this.buildRangeFromDuration(date, direction, duration, unit); 5904 } 5905 else if ((dayCount = this.props.dayCount)) { 5906 unit = 'day'; 5907 range = this.buildRangeFromDayCount(date, direction, dayCount); 5908 } 5909 else if ((range = this.buildCustomVisibleRange(date))) { 5910 unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit; 5911 } 5912 else { 5913 duration = this.getFallbackDuration(); 5914 unit = greatestDurationDenominator(duration).unit; 5915 range = this.buildRangeFromDuration(date, direction, duration, unit); 5916 } 5917 return { duration: duration, unit: unit, range: range }; 5918 }; 5919 DateProfileGenerator.prototype.getFallbackDuration = function () { 5920 return createDuration({ day: 1 }); 5921 }; 5922 // Returns a new activeRange to have time values (un-ambiguate) 5923 // slotMinTime or slotMaxTime causes the range to expand. 5924 DateProfileGenerator.prototype.adjustActiveRange = function (range) { 5925 var _a = this.props, dateEnv = _a.dateEnv, usesMinMaxTime = _a.usesMinMaxTime, slotMinTime = _a.slotMinTime, slotMaxTime = _a.slotMaxTime; 5926 var start = range.start, end = range.end; 5927 if (usesMinMaxTime) { 5928 // expand active range if slotMinTime is negative (why not when positive?) 5929 if (asRoughDays(slotMinTime) < 0) { 5930 start = startOfDay(start); // necessary? 5931 start = dateEnv.add(start, slotMinTime); 5932 } 5933 // expand active range if slotMaxTime is beyond one day (why not when negative?) 5934 if (asRoughDays(slotMaxTime) > 1) { 5935 end = startOfDay(end); // necessary? 5936 end = addDays(end, -1); 5937 end = dateEnv.add(end, slotMaxTime); 5938 } 5939 } 5940 return { start: start, end: end }; 5941 }; 5942 // Builds the "current" range when it is specified as an explicit duration. 5943 // `unit` is the already-computed greatestDurationDenominator unit of duration. 5944 DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) { 5945 var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment; 5946 var start; 5947 var end; 5948 var res; 5949 // compute what the alignment should be 5950 if (!dateAlignment) { 5951 var dateIncrement = this.props.dateIncrement; 5952 if (dateIncrement) { 5953 // use the smaller of the two units 5954 if (asRoughMs(dateIncrement) < asRoughMs(duration)) { 5955 dateAlignment = greatestDurationDenominator(dateIncrement).unit; 5956 } 5957 else { 5958 dateAlignment = unit; 5959 } 5960 } 5961 else { 5962 dateAlignment = unit; 5963 } 5964 }
5965 // if the view displays a single day or smaller 5966 if (asRoughDays(duration) <= 1) { 5967 if (this.isHiddenDay(start)) { 5968 start = this.skipHiddenDays(start, direction); 5969 start = startOfDay(start); 5970 } 5971 } 5972 function computeRes() { 5973 start = dateEnv.startOf(date, dateAlignment); 5974 end = dateEnv.add(start, duration); 5975 res = { start: start, end: end }; 5976 } 5977 computeRes(); 5978 // if range is completely enveloped by hidden days, go past the hidden days 5979 if (!this.trimHiddenDays(res)) { 5980 date = this.skipHiddenDays(date, direction); 5981 computeRes(); 5982 } 5983 return res; 5984 }; 5985 // Builds the "current" range when a dayCount is specified. 5986 DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) { 5987 var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment; 5988 var runningCount = 0; 5989 var start = date; 5990 var end; 5991 if (dateAlignment) { 5992 start = dateEnv.startOf(start, dateAlignment); 5993 } 5994 start = startOfDay(start); 5995 start = this.skipHiddenDays(start, direction); 5996 end = start; 5997 do { 5998 end = addDays(end, 1); 5999 if (!this.isHiddenDay(end)) { 6000 runningCount += 1; 6001 } 6002 } while (runningCount < dayCount); 6003 return { start: start, end: end }; 6004 }; 6005 // Builds a normalized range object for the "visible" range, 6006 // which is a way to define the currentRange and activeRange at the same time. 6007 DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) { 6008 var props = this.props; 6009 var input = props.visibleRangeInput; 6010 var simpleInput = typeof input === 'function' 6011 ? input.call(props.calendarApi, props.dateEnv.toDate(date)) 6012 : input; 6013 var range = this.refineRange(simpleInput); 6014 if (range && (range.start == null || range.end == null)) { 6015 return null; 6016 } 6017 return range; 6018 }; 6019 // Computes the range that will represent the element/cells for *rendering*, 6020 // but which may have voided days/times. 6021 // not responsible for trimming hidden days. 6022 DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) { 6023 return currentRange; 6024 }; 6025 // Compute the duration value that should be added/substracted to the current date 6026 // when a prev/next operation happens. 6027 DateProfileGenerator.prototype.buildDateIncrement = function (fallback) { 6028 var dateIncrement = this.props.dateIncrement; 6029 var customAlignment; 6030 if (dateIncrement) { 6031 return dateIncrement; 6032 } 6033 if ((customAlignment = this.props.dateAlignment)) { 6034 return createDuration(1, customAlignment); 6035 } 6036 if (fallback) { 6037 return fallback; 6038 } 6039 return createDuration({ days: 1 }); 6040 }; 6041 DateProfileGenerator.prototype.refineRange = function (rangeInput) { 6042 if (rangeInput) { 6043 var range = parseRange(rangeInput, this.props.dateEnv); 6044 if (range) { 6045 range = computeVisibleDayRange(range); 6046 } 6047 return range; 6048 } 6049 return null; 6050 }; 6051 /* Hidden Days 6052 ------------------------------------------------------------------------------------------------------------------*/ 6053 // Initializes internal variables related to calculating hidden days-of-week 6054 DateProfileGenerator.prototype.initHiddenDays = function () { 6055 var hiddenDays = this.props.hiddenDays || []; // array of day-of-week indices that are hidden
6056 var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool) 6057 var dayCnt = 0; 6058 var i; 6059 if (this.props.weekends === false) { 6060 hiddenDays.push(0, 6); // 0=sunday, 6=saturday 6061 } 6062 for (i = 0; i < 7; i += 1) { 6063 if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) { 6064 dayCnt += 1; 6065 } 6066 } 6067 if (!dayCnt) { 6068 throw new Error('invalid hiddenDays'); // all days were hidden? bad. 6069 } 6070 this.isHiddenDayHash = isHiddenDayHash; 6071 }; 6072 // Remove days from the beginning and end of the range that are computed as hidden. 6073 // If the whole range is trimmed off, returns null 6074 DateProfileGenerator.prototype.trimHiddenDays = function (range) { 6075 var start = range.start, end = range.end; 6076 if (start) { 6077 start = this.skipHiddenDays(start); 6078 } 6079 if (end) { 6080 end = this.skipHiddenDays(end, -1, true); 6081 } 6082 if (start == null || end == null || start < end) { 6083 return { start: start, end: end }; 6084 } 6085 return null; 6086 }; 6087 // Is the current day hidden? 6088 // `day` is a day-of-week index (0-6), or a Date (used for UTC) 6089 DateProfileGenerator.prototype.isHiddenDay = function (day) { 6090 if (day instanceof Date) { 6091 day = day.getUTCDay(); 6092 } 6093 return this.isHiddenDayHash[day]; 6094 }; 6095 // Incrementing the current day until it is no longer a hidden day, returning a copy. 6096 // DOES NOT CONSIDER validRange! 6097 // If the initial value of `date` is not a hidden day, don't do anything. 6098 // Pass `isExclusive` as `true` if you are dealing with an end date. 6099 // `inc` defaults to `1` (increment one day forward each time) 6100 DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) { 6101 if (inc === void 0) { inc = 1; } 6102 if (isExclusive === void 0) { isExclusive = false; } 6103 while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) { 6104 date = addDays(date, inc); 6105 } 6106 return date; 6107 }; 6108 return DateProfileGenerator; 6109 }()); 6110 6111 function reduceViewType(viewType, action) { 6112 switch (action.type) { 6113 case 'CHANGE_VIEW_TYPE': 6114 viewType = action.viewType; 6115 } 6116 return viewType; 6117 } 6118 6119 function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) { 6120 var _a; 6121 switch (action.type) { 6122 case 'SET_OPTION': 6123 return __assign(__assign({}, dynamicOptionOverrides), (_a = {}, _a[action.optionName] = action.rawOptionValue, _a)); 6124 default: 6125 return dynamicOptionOverrides; 6126 } 6127 } 6128 6129 function reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) { 6130 var dp; 6131 switch (action.type) { 6132 case 'CHANGE_VIEW_TYPE': 6133 return dateProfileGenerator.build(action.dateMarker || currentDate); 6134 case 'CHANGE_DATE': 6135 return dateProfileGenerator.build(action.dateMarker); 6136 case 'PREV': 6137 dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate); 6138 if (dp.isValid) { 6139 return dp; 6140 } 6141 break; 6142 case 'NEXT': 6143 dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate); 6144 if (dp.isValid) { 6145 return dp; 6146 } 6147 break; 6148 } 6149 return currentDateProfile; 6150 } 6151 6152 function initEventSources(calendarOptions, dateProfile, context) { 6153 var activeRange = dateProfile ? dateProfile.activeRange : null; 6154 return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context); 6155 } 6156 function reduceEventSources(eventSources, action, dateProfile, context) { 6157 var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check? 6158 switch (action.type) { 6159 case 'ADD_EVENT_SOURCES': // already parsed 6160 return addSources(eventSources, action.sources, activeRange, context);
6161 case 'REMOVE_EVENT_SOURCE': 6162 return removeSource(eventSources, action.sourceId); 6163 case 'PREV': // TODO: how do we track all actions that affect dateProfile :( 6164 case 'NEXT': 6165 case 'CHANGE_DATE': 6166 case 'CHANGE_VIEW_TYPE': 6167 if (dateProfile) { 6168 return fetchDirtySources(eventSources, activeRange, context); 6169 } 6170 return eventSources; 6171 case 'FETCH_EVENT_SOURCES': 6172 return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type? 6173 arrayToHash(action.sourceIds) : 6174 excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context); 6175 case 'RECEIVE_EVENTS': 6176 case 'RECEIVE_EVENT_ERROR': 6177 return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange); 6178 case 'REMOVE_ALL_EVENT_SOURCES': 6179 return {}; 6180 default: 6181 return eventSources; 6182 } 6183 } 6184 function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) { 6185 var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check? 6186 return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context); 6187 } 6188 function computeEventSourcesLoading(eventSources) { 6189 for (var sourceId in eventSources) { 6190 if (eventSources[sourceId].isFetching) { 6191 return true; 6192 } 6193 } 6194 return false; 6195 } 6196 function addSources(eventSourceHash, sources, fetchRange, context) { 6197 var hash = {}; 6198 for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) { 6199 var source = sources_1[_i]; 6200 hash[source.sourceId] = source; 6201 } 6202 if (fetchRange) { 6203 hash = fetchDirtySources(hash, fetchRange, context); 6204 } 6205 return __assign(__assign({}, eventSourceHash), hash); 6206 } 6207 function removeSource(eventSourceHash, sourceId) { 6208 return filterHash(eventSourceHash, function (eventSource) { return eventSource.sourceId !== sourceId; }); 6209 } 6210 function fetchDirtySources(sourceHash, fetchRange, context) { 6211 return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) { return isSourceDirty(eventSource, fetchRange, context); }), fetchRange, false, context); 6212 } 6213 function isSourceDirty(eventSource, fetchRange, context) { 6214 if (!doesSourceNeedRange(eventSource, context)) { 6215 return !eventSource.latestFetchId; 6216 } 6217 return !context.options.lazyFetching || 6218 !eventSource.fetchRange || 6219 eventSource.isFetching || // always cancel outdated in-progress fetches 6220 fetchRange.start < eventSource.fetchRange.start || 6221 fetchRange.end > eventSource.fetchRange.end; 6222 } 6223 function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) { 6224 var nextSources = {}; 6225 for (var sourceId in prevSources) { 6226 var source = prevSources[sourceId]; 6227 if (sourceIdHash[sourceId]) { 6228 nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context); 6229 } 6230 else { 6231 nextSources[sourceId] = source; 6232 } 6233 } 6234 return nextSources; 6235 } 6236 function fetchSource(eventSource, fetchRange, isRefetch, context) { 6237 var options = context.options, calendarApi = context.calendarApi; 6238 var sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId]; 6239 var fetchId = guid(); 6240 sourceDef.fetch({ 6241 eventSource: eventSource, 6242 range: fetchRange, 6243 isRefetch: isRefetch, 6244 context: context, 6245 }, function (res) { 6246 var rawEvents = res.rawEvents; 6247 if (options.eventSourceSuccess) { 6248 rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.xhr) || rawEvents; 6249 } 6250 if (eventSource.success) { 6251 rawEvents = eventSource.success.call(calendarApi, rawEvents, res.xhr) || rawEvents; 6252 } 6253 context.dispatch({ 6254 type: 'RECEIVE_EVENTS', 6255 sourceId: eventSource.sourceId, 6256 fetchId: fetchId, 6257 fetchRange: fetchRange, 6258 rawEvents: rawEvents, 6259 }); 6260 }, function (error) { 6261 console.warn(error.message, error); 6262 if (options.eventSourceFailure) { 6263 options.eventSourceFailure.call(calendarApi, error); 6264 } 6265 if (eventSource.failure) { 6266 eventSource.failure(error); 6267 } 6268 context.dispatch({ 6269 type: 'RECEIVE_EVENT_ERROR', 6270 sourceId: eventSource.sourceId, 6271 fetchId: fetchId, 6272 fetchRange: fetchRange, 6273 error: error, 6274 }); 6275 }); 6276 return __assign(__assign({}, eventSource), { isFetching: true, latestFetchId: fetchId }); 6277 } 6278 function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) { 6279 var _a; 6280 var eventSource = sourceHash[sourceId]; 6281 if (eventSource && // not already removed 6282 fetchId === eventSource.latestFetchId) { 6283 return __assign(__assign({}, sourceHash), (_a = {}, _a[sourceId] = __assign(__assign({}, eventSource), { isFetching: false, fetchRange: fetchRange }), _a)); 6284 } 6285 return sourceHash; 6286 } 6287 function excludeStaticSources(eventSources, context) { 6288 return filterHash(eventSources, function (eventSource) { return doesSourceNeedRange(eventSource, context); }); 6289 } 6290 function parseInitialSources(rawOptions, context) { 6291 var refiners = buildEventSourceRefiners(context); 6292 var rawSources = [].concat(rawOptions.eventSources || []); 6293 var sources = []; // parsed 6294 if (rawOptions.initialEvents) { 6295 rawSources.unshift(rawOptions.initialEvents); 6296 } 6297 if (rawOptions.events) { 6298 rawSources.unshift(rawOptions.events); 6299 } 6300 for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) { 6301 var rawSource = rawSources_1[_i]; 6302 var source = parseEventSource(rawSource, context, refiners); 6303 if (source) { 6304 sources.push(source); 6305 } 6306 } 6307 return sources; 6308 } 6309 function doesSourceNeedRange(eventSource, context) { 6310 var defs = context.pluginHooks.eventSourceDefs; 6311 return !defs[eventSource.sourceDefId].ignoreRange; 6312 } 6313 6314 function reduceEventStore(eventStore, action, eventSources, dateProfile, context) { 6315 switch (action.type) { 6316 case 'RECEIVE_EVENTS': // raw 6317 return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context); 6318 case 'ADD_EVENTS': // already parsed, but not expanded 6319 return addEvent(eventStore, action.eventStore, // new ones 6320 dateProfile ? dateProfile.activeRange : null, context); 6321 case 'RESET_EVENTS': 6322 return action.eventStore; 6323 case 'MERGE_EVENTS': // already parsed and expanded 6324 return mergeEventStores(eventStore, action.eventStore); 6325 case 'PREV': // TODO: how do we track all actions that affect dateProfile :( 6326 case 'NEXT': 6327 case 'CHANGE_DATE': 6328 case 'CHANGE_VIEW_TYPE': 6329 if (dateProfile) { 6330 return expandRecurring(eventStore, dateProfile.activeRange, context); 6331 } 6332 return eventStore;
6333 case 'REMOVE_EVENTS': 6334 return excludeSubEventStore(eventStore, action.eventStore); 6335 case 'REMOVE_EVENT_SOURCE': 6336 return excludeEventsBySourceId(eventStore, action.sourceId); 6337 case 'REMOVE_ALL_EVENT_SOURCES': 6338 return filterEventStoreDefs(eventStore, function (eventDef) { return (!eventDef.sourceId // only keep events with no source id 6339 ); }); 6340 case 'REMOVE_ALL_EVENTS': 6341 return createEmptyEventStore(); 6342 default: 6343 return eventStore; 6344 } 6345 } 6346 function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) { 6347 if (eventSource && // not already removed 6348 fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources 6349 ) { 6350 var subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context); 6351 if (fetchRange) { 6352 subset = expandRecurring(subset, fetchRange, context); 6353 } 6354 return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset); 6355 } 6356 return eventStore; 6357 } 6358 function transformRawEvents(rawEvents, eventSource, context) { 6359 var calEachTransform = context.options.eventDataTransform; 6360 var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null; 6361 if (sourceEachTransform) { 6362 rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform); 6363 } 6364 if (calEachTransform) { 6365 rawEvents = transformEachRawEvent(rawEvents, calEachTransform); 6366 } 6367 return rawEvents; 6368 } 6369 function transformEachRawEvent(rawEvents, func) { 6370 var refinedEvents; 6371 if (!func) { 6372 refinedEvents = rawEvents; 6373 } 6374 else { 6375 refinedEvents = []; 6376 for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) { 6377 var rawEvent = rawEvents_1[_i]; 6378 var refinedEvent = func(rawEvent); 6379 if (refinedEvent) { 6380 refinedEvents.push(refinedEvent); 6381 } 6382 else if (refinedEvent == null) { 6383 refinedEvents.push(rawEvent); 6384 } // if a different falsy value, do nothing 6385 } 6386 } 6387 return refinedEvents; 6388 } 6389 function addEvent(eventStore, subset, expandRange, context) { 6390 if (expandRange) { 6391 subset = expandRecurring(subset, expandRange, context); 6392 } 6393 return mergeEventStores(eventStore, subset); 6394 } 6395 function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) { 6396 var defs = eventStore.defs; 6397 var instances = mapHash(eventStore.instances, function (instance) { 6398 var def = defs[instance.defId]; 6399 if (def.allDay || def.recurringDef) { 6400 return instance; // isn't dependent on timezone 6401 } 6402 return __assign(__assign({}, instance), { range: { 6403 start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)), 6404 end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo)), 6405 }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo }); 6406 }); 6407 return { defs: defs, instances: instances }; 6408 } 6409 function excludeEventsBySourceId(eventStore, sourceId) { 6410 return filterEventStoreDefs(eventStore, function (eventDef) { return eventDef.sourceId !== sourceId; }); 6411 } 6412 // QUESTION: why not just return instances? do a general object-property-exclusion util 6413 function excludeInstances(eventStore, removals) { 6414 return { 6415 defs: eventStore.defs, 6416 instances: filterHash(eventStore.instances, function (instance) { return !removals[instance.instanceId]; }), 6417 }; 6418 } 6419 6420 function reduceDateSelection(currentSelection, action) { 6421 switch (action.type) { 6422 case 'UNSELECT_DATES': 6423 return null; 6424 case 'SELECT_DATES': 6425 return action.selection; 6426 default: 6427 return currentSelection; 6428 } 6429 } 6430 6431 function reduceSelectedEvent(currentInstanceId, action) { 6432 switch (action.type) { 6433 case 'UNSELECT_EVENT': 6434 return ''; 6435 case 'SELECT_EVENT': 6436 return action.eventInstanceId; 6437 default: 6438 return currentInstanceId; 6439 } 6440 } 6441 6442 function reduceEventDrag(currentDrag, action) { 6443 var newDrag; 6444 switch (action.type) { 6445 case 'UNSET_EVENT_DRAG': 6446 return null; 6447 case 'SET_EVENT_DRAG': 6448 newDrag = action.state; 6449 return { 6450 affectedEvents: newDrag.affectedEvents, 6451 mutatedEvents: newDrag.mutatedEvents, 6452 isEvent: newDrag.isEvent, 6453 }; 6454 default: 6455 return currentDrag; 6456 } 6457 } 6458 6459 function reduceEventResize(currentResize, action) { 6460 var newResize; 6461 switch (action.type) { 6462 case 'UNSET_EVENT_RESIZE': 6463 return null; 6464 case 'SET_EVENT_RESIZE': 6465 newResize = action.state; 6466 return { 6467 affectedEvents: newResize.affectedEvents, 6468 mutatedEvents: newResize.mutatedEvents, 6469 isEvent: newResize.isEvent, 6470 }; 6471 default: 6472 return currentResize; 6473 } 6474 } 6475 6476 function parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) { 6477 var header = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null; 6478 var footer = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null; 6479 return { header: header, footer: footer }; 6480 } 6481 function parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) { 6482 var sectionWidgets = {}; 6483 var viewsWithButtons = []; 6484 var hasTitle = false;
6485 for (var sectionName in sectionStrHash) { 6486 var sectionStr = sectionStrHash[sectionName]; 6487 var sectionRes = parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi); 6488 sectionWidgets[sectionName] = sectionRes.widgets; 6489 viewsWithButtons.push.apply(viewsWithButtons, sectionRes.viewsWithButtons); 6490 hasTitle = hasTitle || sectionRes.hasTitle; 6491 } 6492 return { sectionWidgets: sectionWidgets, viewsWithButtons: viewsWithButtons, hasTitle: hasTitle }; 6493 } 6494 /* 6495 BAD: querying icons and text here. should be done at render time 6496 */ 6497 function parseSection(sectionStr, calendarOptions, // defaults+overrides, then refined 6498 calendarOptionOverrides, // overrides only!, unrefined :( 6499 theme, viewSpecs, calendarApi) { 6500 var isRtl = calendarOptions.direction === 'rtl'; 6501 var calendarCustomButtons = calendarOptions.customButtons || {}; 6502 var calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {}; 6503 var calendarButtonText = calendarOptions.buttonText || {}; 6504 var calendarButtonHintOverrides = calendarOptionOverrides.buttonHints || {}; 6505 var calendarButtonHints = calendarOptions.buttonHints || {}; 6506 var sectionSubstrs = sectionStr ? sectionStr.split(' ') : []; 6507 var viewsWithButtons = []; 6508 var hasTitle = false; 6509 var widgets = sectionSubstrs.map(function (buttonGroupStr) { return (buttonGroupStr.split(',').map(function (buttonName) { 6510 if (buttonName === 'title') { 6511 hasTitle = true; 6512 return { buttonName: buttonName }; 6513 } 6514 var customButtonProps; 6515 var viewSpec; 6516 var buttonClick; 6517 var buttonIcon; // only one of these will be set 6518 var buttonText; // " 6519 var buttonHint; 6520 // ^ for the title="" attribute, for accessibility 6521 if ((customButtonProps = calendarCustomButtons[buttonName])) { 6522 buttonClick = function (ev) { 6523 if (customButtonProps.click) { 6524 customButtonProps.click.call(ev.target, ev, ev.target); // TODO: use Calendar this context? 6525 } 6526 }; 6527 (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) || 6528 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6529 (buttonText = customButtonProps.text); 6530 buttonHint = customButtonProps.hint || customButtonProps.text; 6531 } 6532 else if ((viewSpec = viewSpecs[buttonName])) { 6533 viewsWithButtons.push(buttonName); 6534 buttonClick = function () { 6535 calendarApi.changeView(buttonName); 6536 }; 6537 (buttonText = viewSpec.buttonTextOverride) || 6538 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6539 (buttonText = viewSpec.buttonTextDefault); 6540 var textFallback = viewSpec.buttonTextOverride || 6541 viewSpec.buttonTextDefault; 6542 buttonHint = formatWithOrdinals(viewSpec.buttonTitleOverride || 6543 viewSpec.buttonTitleDefault || 6544 calendarOptions.viewHint, [textFallback, buttonName], // view-name = buttonName 6545 textFallback); 6546 } 6547 else if (calendarApi[buttonName]) { // a calendarApi method 6548 buttonClick = function () { 6549 calendarApi[buttonName](); 6550 }; 6551 (buttonText = calendarButtonTextOverrides[buttonName]) || 6552 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6553 (buttonText = calendarButtonText[buttonName]); // everything else is considered default 6554 if (buttonName === 'prevYear' || buttonName === 'nextYear') { 6555 var prevOrNext = buttonName === 'prevYear' ? 'prev' : 'next'; 6556 buttonHint = formatWithOrdinals(calendarButtonHintOverrides[prevOrNext] || 6557 calendarButtonHints[prevOrNext], [ 6558 calendarButtonText.year || 'year', 6559 'year', 6560 ], calendarButtonText[buttonName]); 6561 } 6562 else { 6563 buttonHint = function (navUnit) { return formatWithOrdinals(calendarButtonHintOverrides[buttonName] || 6564 calendarButtonHints[buttonName], [ 6565 calendarButtonText[navUnit] || navUnit, 6566 navUnit, 6567 ], calendarButtonText[buttonName]); }; 6568 } 6569 } 6570 return { buttonName: buttonName, buttonClick: buttonClick, buttonIcon: buttonIcon, buttonText: buttonText, buttonHint: buttonHint }; 6571 })); }); 6572 return { widgets: widgets, viewsWithButtons: viewsWithButtons, hasTitle: hasTitle }; 6573 } 6574 6575 var eventSourceDef$3 = { 6576 ignoreRange: true, 6577 parseMeta: function (refined) { 6578 if (Array.isArray(refined.events)) { 6579 return refined.events; 6580 } 6581 return null; 6582 }, 6583 fetch: function (arg, success) { 6584 success({ 6585 rawEvents: arg.eventSource.meta, 6586 }); 6587 }, 6588 }; 6589 var arrayEventSourcePlugin = createPlugin({ 6590 eventSourceDefs: [eventSourceDef$3], 6591 }); 6592 6593 var eventSourceDef$2 = { 6594 parseMeta: function (refined) { 6595 if (typeof refined.events === 'function') { 6596 return refined.events; 6597 } 6598 return null; 6599 }, 6600 fetch: function (arg, success, failure) { 6601 var dateEnv = arg.context.dateEnv; 6602 var func = arg.eventSource.meta; 6603 unpromisify(func.bind(null, buildRangeApiWithTimeZone(arg.range, dateEnv)), function (rawEvents) { 6604 success({ rawEvents: rawEvents }); // needs an object response 6605 }, failure); 6606 }, 6607 }; 6608 var funcEventSourcePlugin = createPlugin({ 6609 eventSourceDefs: [eventSourceDef$2], 6610 }); 6611 6612 function requestJson(method, url, params, successCallback, failureCallback) { 6613 method = method.toUpperCase(); 6614 var body = null; 6615 if (method === 'GET') { 6616 url = injectQueryStringParams(url, params); 6617 } 6618 else { 6619 body = encodeParams(params); 6620 } 6621 var xhr = new XMLHttpRequest(); 6622 xhr.open(method, url, true); 6623 if (method !== 'GET') { 6624 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 6625 } 6626 xhr.onload = function () { 6627 if (xhr.status >= 200 && xhr.status < 400) { 6628 var parsed = false;
6629 var res = void 0; 6630 try { 6631 res = JSON.parse(xhr.responseText); 6632 parsed = true; 6633 } 6634 catch (err) { 6635 // will handle parsed=false 6636 } 6637 if (parsed) { 6638 successCallback(res, xhr); 6639 } 6640 else { 6641 failureCallback('Failure parsing JSON', xhr); 6642 } 6643 } 6644 else { 6645 failureCallback('Request failed', xhr); 6646 } 6647 }; 6648 xhr.onerror = function () { 6649 failureCallback('Request failed', xhr); 6650 }; 6651 xhr.send(body); 6652 } 6653 function injectQueryStringParams(url, params) { 6654 return url + 6655 (url.indexOf('?') === -1 ? '?' : '&') + 6656 encodeParams(params); 6657 } 6658 function encodeParams(params) { 6659 var parts = []; 6660 for (var key in params) { 6661 parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key])); 6662 } 6663 return parts.join('&'); 6664 } 6665 6666 var JSON_FEED_EVENT_SOURCE_REFINERS = { 6667 method: String, 6668 extraParams: identity, 6669 startParam: String, 6670 endParam: String, 6671 timeZoneParam: String, 6672 }; 6673 6674 var eventSourceDef$1 = { 6675 parseMeta: function (refined) { 6676 if (refined.url && (refined.format === 'json' || !refined.format)) { 6677 return { 6678 url: refined.url, 6679 format: 'json', 6680 method: (refined.method || 'GET').toUpperCase(), 6681 extraParams: refined.extraParams, 6682 startParam: refined.startParam, 6683 endParam: refined.endParam, 6684 timeZoneParam: refined.timeZoneParam, 6685 }; 6686 } 6687 return null; 6688 }, 6689 fetch: function (arg, success, failure) { 6690 var meta = arg.eventSource.meta; 6691 var requestParams = buildRequestParams$1(meta, arg.range, arg.context); 6692 requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) { 6693 success({ rawEvents: rawEvents, xhr: xhr }); 6694 }, function (errorMessage, xhr) { 6695 failure({ message: errorMessage, xhr: xhr }); 6696 }); 6697 }, 6698 }; 6699 var jsonFeedEventSourcePlugin = createPlugin({ 6700 eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS, 6701 eventSourceDefs: [eventSourceDef$1], 6702 }); 6703 function buildRequestParams$1(meta, range, context) { 6704 var dateEnv = context.dateEnv, options = context.options; 6705 var startParam; 6706 var endParam; 6707 var timeZoneParam;
6708 var customRequestParams; 6709 var params = {}; 6710 startParam = meta.startParam; 6711 if (startParam == null) { 6712 startParam = options.startParam; 6713 } 6714 endParam = meta.endParam; 6715 if (endParam == null) { 6716 endParam = options.endParam; 6717 } 6718 timeZoneParam = meta.timeZoneParam; 6719 if (timeZoneParam == null) { 6720 timeZoneParam = options.timeZoneParam; 6721 } 6722 // retrieve any outbound GET/POST data from the options 6723 if (typeof meta.extraParams === 'function') { 6724 // supplied as a function that returns a key/value object 6725 customRequestParams = meta.extraParams(); 6726 } 6727 else { 6728 // probably supplied as a straight key/value object 6729 customRequestParams = meta.extraParams || {}; 6730 } 6731 __assign(params, customRequestParams); 6732 params[startParam] = dateEnv.formatIso(range.start); 6733 params[endParam] = dateEnv.formatIso(range.end); 6734 if (dateEnv.timeZone !== 'local') { 6735 params[timeZoneParam] = dateEnv.timeZone; 6736 } 6737 return params; 6738 } 6739 6740 var SIMPLE_RECURRING_REFINERS = { 6741 daysOfWeek: identity, 6742 startTime: createDuration, 6743 endTime: createDuration, 6744 duration: createDuration, 6745 startRecur: identity, 6746 endRecur: identity, 6747 }; 6748 6749 var recurring = { 6750 parse: function (refined, dateEnv) { 6751 if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) { 6752 var recurringData = { 6753 daysOfWeek: refined.daysOfWeek || null, 6754 startTime: refined.startTime || null, 6755 endTime: refined.endTime || null, 6756 startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null, 6757 endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null, 6758 }; 6759 var duration = void 0; 6760 if (refined.duration) { 6761 duration = refined.duration; 6762 } 6763 if (!duration && refined.startTime && refined.endTime) { 6764 duration = subtractDurations(refined.endTime, refined.startTime); 6765 } 6766 return { 6767 allDayGuess: Boolean(!refined.startTime && !refined.endTime), 6768 duration: duration, 6769 typeData: recurringData, // doesn't need endTime anymore but oh well 6770 }; 6771 } 6772 return null; 6773 }, 6774 expand: function (typeData, framingRange, dateEnv) { 6775 var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur }); 6776 if (clippedFramingRange) { 6777 return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv); 6778 } 6779 return []; 6780 }, 6781 }; 6782 var simpleRecurringEventsPlugin = createPlugin({ 6783 recurringTypes: [recurring], 6784 eventRefiners: SIMPLE_RECURRING_REFINERS, 6785 }); 6786 function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) { 6787 var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null; 6788 var dayMarker = startOfDay(framingRange.start); 6789 var endMarker = framingRange.end; 6790 var instanceStarts = []; 6791 while (dayMarker < endMarker) { 6792 var instanceStart 6793 // if everyday, or this particular day-of-week 6794 = void 0; 6795 // if everyday, or this particular day-of-week 6796 if (!dowHash || dowHash[dayMarker.getUTCDay()]) { 6797 if (startTime) { 6798 instanceStart = dateEnv.add(dayMarker, startTime); 6799 } 6800 else { 6801 instanceStart = dayMarker; 6802 } 6803 instanceStarts.push(instanceStart); 6804 } 6805 dayMarker = addDays(dayMarker, 1); 6806 } 6807 return instanceStarts; 6808 } 6809 6810 var changeHandlerPlugin = createPlugin({ 6811 optionChangeHandlers: { 6812 events: function (events, context) { 6813 handleEventSources([events], context); 6814 }, 6815 eventSources: handleEventSources, 6816 }, 6817 }); 6818 /* 6819 BUG: if `event` was supplied, all previously-given `eventSources` will be wiped out 6820 */ 6821 function handleEventSources(inputs, context) { 6822 var unfoundSources = hashValuesToArray(context.getCurrentData().eventSources);
6823 var newInputs = []; 6824 for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) { 6825 var input = inputs_1[_i]; 6826 var inputFound = false; 6827 for (var i = 0; i < unfoundSources.length; i += 1) { 6828 if (unfoundSources[i]._raw === input) { 6829 unfoundSources.splice(i, 1); // delete 6830 inputFound = true; 6831 break; 6832 } 6833 } 6834 if (!inputFound) { 6835 newInputs.push(input); 6836 } 6837 } 6838 for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) { 6839 var unfoundSource = unfoundSources_1[_a]; 6840 context.dispatch({ 6841 type: 'REMOVE_EVENT_SOURCE', 6842 sourceId: unfoundSource.sourceId, 6843 }); 6844 } 6845 for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) { 6846 var newInput = newInputs_1[_b]; 6847 context.calendarApi.addEventSource(newInput); 6848 } 6849 } 6850 6851 function handleDateProfile(dateProfile, context) { 6852 context.emitter.trigger('datesSet', __assign(__assign({}, buildRangeApiWithTimeZone(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi })); 6853 } 6854 6855 function handleEventStore(eventStore, context) { 6856 var emitter = context.emitter; 6857 if (emitter.hasHandlers('eventsSet')) { 6858 emitter.trigger('eventsSet', buildEventApis(eventStore, context)); 6859 } 6860 } 6861 6862 /* 6863 this array is exposed on the root namespace so that UMD plugins can add to it. 6864 see the rollup-bundles script. 6865 */ 6866 var globalPlugins = [ 6867 arrayEventSourcePlugin, 6868 funcEventSourcePlugin, 6869 jsonFeedEventSourcePlugin, 6870 simpleRecurringEventsPlugin, 6871 changeHandlerPlugin, 6872 createPlugin({ 6873 isLoadingFuncs: [ 6874 function (state) { return computeEventSourcesLoading(state.eventSources); }, 6875 ], 6876 contentTypeHandlers: { 6877 html: buildHtmlRenderer, 6878 domNodes: buildDomNodeRenderer, 6879 }, 6880 propSetHandlers: { 6881 dateProfile: handleDateProfile, 6882 eventStore: handleEventStore, 6883 }, 6884 }), 6885 ]; 6886 function buildHtmlRenderer() { 6887 var currentEl = null; 6888 var currentHtml = ''; 6889 function render(el, html) { 6890 if (el !== currentEl || html !== currentHtml) { 6891 el.innerHTML = html; 6892 } 6893 currentEl = el; 6894 currentHtml = html; 6895 } 6896 function destroy() { 6897 currentEl.innerHTML = ''; 6898 currentEl = null; 6899 currentHtml = ''; 6900 } 6901 return { render: render, destroy: destroy }; 6902 } 6903 function buildDomNodeRenderer() { 6904 var currentEl = null; 6905 var currentDomNodes = []; 6906 function render(el, domNodes) { 6907 var newDomNodes = Array.prototype.slice.call(domNodes); 6908 if (el !== currentEl || !isArraysEqual(currentDomNodes, newDomNodes)) { 6909 // append first, remove second (for scroll resetting) 6910 for (var _i = 0, newDomNodes_1 = newDomNodes; _i < newDomNodes_1.length; _i++) { 6911 var newNode = newDomNodes_1[_i]; 6912 el.appendChild(newNode); 6913 } 6914 destroy(); 6915 } 6916 currentEl = el; 6917 currentDomNodes = newDomNodes; 6918 } 6919 function destroy() { 6920 currentDomNodes.forEach(removeElement); 6921 currentDomNodes = []; 6922 currentEl = null; 6923 } 6924 return { render: render, destroy: destroy }; 6925 } 6926 6927 var DelayedRunner = /** @class */ (function () { 6928 function DelayedRunner(drainedOption) { 6929 this.drainedOption = drainedOption; 6930 this.isRunning = false; 6931 this.isDirty = false; 6932 this.pauseDepths = {}; 6933 this.timeoutId = 0; 6934 } 6935 DelayedRunner.prototype.request = function (delay) { 6936 this.isDirty = true; 6937 if (!this.isPaused()) { 6938 this.clearTimeout(); 6939 if (delay == null) { 6940 this.tryDrain(); 6941 } 6942 else { 6943 this.timeoutId = setTimeout(// NOT OPTIMAL! TODO: look at debounce 6944 this.tryDrain.bind(this), delay); 6945 } 6946 } 6947 }; 6948 DelayedRunner.prototype.pause = function (scope) { 6949 if (scope === void 0) { scope = ''; } 6950 var pauseDepths = this.pauseDepths; 6951 pauseDepths[scope] = (pauseDepths[scope] || 0) + 1; 6952 this.clearTimeout(); 6953 }; 6954 DelayedRunner.prototype.resume = function (scope, force) { 6955 if (scope === void 0) { scope = ''; } 6956 var pauseDepths = this.pauseDepths; 6957 if (scope in pauseDepths) { 6958 if (force) { 6959 delete pauseDepths[scope]; 6960 } 6961 else { 6962 pauseDepths[scope] -= 1; 6963 var depth = pauseDepths[scope]; 6964 if (depth <= 0) { 6965 delete pauseDepths[scope]; 6966 } 6967 } 6968 this.tryDrain(); 6969 } 6970 }; 6971 DelayedRunner.prototype.isPaused = function () { 6972 return Object.keys(this.pauseDepths).length; 6973 }; 6974 DelayedRunner.prototype.tryDrain = function () { 6975 if (!this.isRunning && !this.isPaused()) { 6976 this.isRunning = true; 6977 while (this.isDirty) { 6978 this.isDirty = false;
6979 this.drained(); // might set isDirty to true again 6980 } 6981 this.isRunning = false; 6982 } 6983 }; 6984 DelayedRunner.prototype.clear = function () { 6985 this.clearTimeout(); 6986 this.isDirty = false; 6987 this.pauseDepths = {}; 6988 }; 6989 DelayedRunner.prototype.clearTimeout = function () { 6990 if (this.timeoutId) { 6991 clearTimeout(this.timeoutId); 6992 this.timeoutId = 0; 6993 } 6994 }; 6995 DelayedRunner.prototype.drained = function () { 6996 if (this.drainedOption) { 6997 this.drainedOption(); 6998 } 6999 }; 7000 return DelayedRunner; 7001 }()); 7002 7003 var TaskRunner = /** @class */ (function () { 7004 function TaskRunner(runTaskOption, drainedOption) { 7005 this.runTaskOption = runTaskOption; 7006 this.drainedOption = drainedOption; 7007 this.queue = []; 7008 this.delayedRunner = new DelayedRunner(this.drain.bind(this)); 7009 } 7010 TaskRunner.prototype.request = function (task, delay) { 7011 this.queue.push(task); 7012 this.delayedRunner.request(delay); 7013 }; 7014 TaskRunner.prototype.pause = function (scope) { 7015 this.delayedRunner.pause(scope); 7016 }; 7017 TaskRunner.prototype.resume = function (scope, force) { 7018 this.delayedRunner.resume(scope, force); 7019 }; 7020 TaskRunner.prototype.drain = function () { 7021 var queue = this.queue; 7022 while (queue.length) { 7023 var completedTasks = []; 7024 var task = void 0; 7025 while ((task = queue.shift())) { 7026 this.runTask(task); 7027 completedTasks.push(task); 7028 } 7029 this.drained(completedTasks); 7030 } // keep going, in case new tasks were added in the drained handler 7031 }; 7032 TaskRunner.prototype.runTask = function (task) { 7033 if (this.runTaskOption) { 7034 this.runTaskOption(task); 7035 } 7036 }; 7037 TaskRunner.prototype.drained = function (completedTasks) { 7038 if (this.drainedOption) { 7039 this.drainedOption(completedTasks); 7040 } 7041 }; 7042 return TaskRunner; 7043 }()); 7044 7045 // Computes what the title at the top of the calendarApi should be for this view 7046 function buildTitle(dateProfile, viewOptions, dateEnv) { 7047 var range; 7048 // for views that span a large unit of time, show the proper interval, ignoring stray days before and after 7049 if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) { 7050 range = dateProfile.currentRange; 7051 } 7052 else { // for day units or smaller, use the actual day range 7053 range = dateProfile.activeRange; 7054 } 7055 return dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || buildTitleFormat(dateProfile)), { 7056 isEndExclusive: dateProfile.isRangeAllDay, 7057 defaultSeparator: viewOptions.titleRangeSeparator, 7058 }); 7059 } 7060 // Generates the format string that should be used to generate the title for the current date range. 7061 // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`. 7062 function buildTitleFormat(dateProfile) { 7063 var currentRangeUnit = dateProfile.currentRangeUnit; 7064 if (currentRangeUnit === 'year') { 7065 return { year: 'numeric' }; 7066 } 7067 if (currentRangeUnit === 'month') { 7068 return { year: 'numeric', month: 'long' }; // like "September 2014" 7069 } 7070 var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end); 7071 if (days !== null && days > 1) { 7072 // multi-day range. shorter, like "Sep 9 - 10 2014" 7073 return { year: 'numeric', month: 'short', day: 'numeric' }; 7074 } 7075 // one day. longer, like "September 9 2014" 7076 return { year: 'numeric', month: 'long', day: 'numeric' }; 7077 } 7078 7079 // in future refactor, do the redux-style function(state=initial) for initial-state 7080 // also, whatever is happening in constructor, have it happen in action queue too 7081 var CalendarDataManager = /** @class */ (function () { 7082 function CalendarDataManager(props) { 7083 var _this = this; 7084 this.computeOptionsData = memoize(this._computeOptionsData); 7085 this.computeCurrentViewData = memoize(this._computeCurrentViewData);
7086 this.organizeRawLocales = memoize(organizeRawLocales); 7087 this.buildLocale = memoize(buildLocale); 7088 this.buildPluginHooks = buildBuildPluginHooks(); 7089 this.buildDateEnv = memoize(buildDateEnv); 7090 this.buildTheme = memoize(buildTheme); 7091 this.parseToolbars = memoize(parseToolbars); 7092 this.buildViewSpecs = memoize(buildViewSpecs); 7093 this.buildDateProfileGenerator = memoizeObjArg(buildDateProfileGenerator); 7094 this.buildViewApi = memoize(buildViewApi); 7095 this.buildViewUiProps = memoizeObjArg(buildViewUiProps); 7096 this.buildEventUiBySource = memoize(buildEventUiBySource, isPropsEqual); 7097 this.buildEventUiBases = memoize(buildEventUiBases); 7098 this.parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours); 7099 this.buildTitle = memoize(buildTitle); 7100 this.emitter = new Emitter(); 7101 this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this)); 7102 this.currentCalendarOptionsInput = {}; 7103 this.currentCalendarOptionsRefined = {}; 7104 this.currentViewOptionsInput = {}; 7105 this.currentViewOptionsRefined = {}; 7106 this.currentCalendarOptionsRefiners = {}; 7107 this.getCurrentData = function () { return _this.data; }; 7108 this.dispatch = function (action) { 7109 _this.actionRunner.request(action); // protects against recursive calls to _handleAction 7110 }; 7111 this.props = props; 7112 this.actionRunner.pause(); 7113 var dynamicOptionOverrides = {}; 7114 var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi); 7115 var currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView; 7116 var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides); 7117 // wire things up 7118 // TODO: not DRY 7119 props.calendarApi.currentDataManager = this; 7120 this.emitter.setThisContext(props.calendarApi); 7121 this.emitter.setOptions(currentViewData.options); 7122 var currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv); 7123 var dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 7124 if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) { 7125 currentDate = dateProfile.currentRange.start; 7126 } 7127 var calendarContext = { 7128 dateEnv: optionsData.dateEnv, 7129 options: optionsData.calendarOptions, 7130 pluginHooks: optionsData.pluginHooks, 7131 calendarApi: props.calendarApi, 7132 dispatch: this.dispatch, 7133 emitter: this.emitter, 7134 getCurrentData: this.getCurrentData, 7135 }; 7136 // needs to be after setThisContext 7137 for (var _i = 0, _a = optionsData.pluginHooks.contextInit; _i < _a.length; _i++) { 7138 var callback = _a[_i]; 7139 callback(calendarContext); 7140 } 7141 // NOT DRY 7142 var eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext); 7143 var initialState = { 7144 dynamicOptionOverrides: dynamicOptionOverrides, 7145 currentViewType: currentViewType, 7146 currentDate: currentDate, 7147 dateProfile: dateProfile, 7148 businessHours: this.parseContextBusinessHours(calendarContext), 7149 eventSources: eventSources, 7150 eventUiBases: {}, 7151 eventStore: createEmptyEventStore(), 7152 renderableEventStore: createEmptyEventStore(), 7153 dateSelection: null, 7154 eventSelection: '', 7155 eventDrag: null, 7156 eventResize: null, 7157 selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig, 7158 }; 7159 var contextAndState = __assign(__assign({}, calendarContext), initialState); 7160 for (var _b = 0, _c = optionsData.pluginHooks.reducers; _b < _c.length; _b++) { 7161 var reducer = _c[_b]; 7162 __assign(initialState, reducer(null, null, contextAndState)); 7163 } 7164 if (computeIsLoading(initialState, calendarContext)) { 7165 this.emitter.trigger('loading', true); // NOT DRY 7166 } 7167 this.state = initialState; 7168 this.updateData(); 7169 this.actionRunner.resume(); 7170 } 7171 CalendarDataManager.prototype.resetOptions = function (optionOverrides, append) { 7172 var props = this.props; 7173 props.optionOverrides = append 7174 ? __assign(__assign({}, props.optionOverrides), optionOverrides) : optionOverrides; 7175 this.actionRunner.request({ 7176 type: 'NOTHING', 7177 }); 7178 }; 7179 CalendarDataManager.prototype._handleAction = function (action) { 7180 var _a = this, props = _a.props, state = _a.state, emitter = _a.emitter; 7181 var dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action); 7182 var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi); 7183 var currentViewType = reduceViewType(state.currentViewType, action); 7184 var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides); 7185 // wire things up 7186 // TODO: not DRY 7187 props.calendarApi.currentDataManager = this; 7188 emitter.setThisContext(props.calendarApi); 7189 emitter.setOptions(currentViewData.options); 7190 var calendarContext = { 7191 dateEnv: optionsData.dateEnv, 7192 options: optionsData.calendarOptions, 7193 pluginHooks: optionsData.pluginHooks, 7194 calendarApi: props.calendarApi, 7195 dispatch: this.dispatch, 7196 emitter: emitter, 7197 getCurrentData: this.getCurrentData, 7198 }; 7199 var currentDate = state.currentDate, dateProfile = state.dateProfile; 7200 if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack 7201 dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 7202 } 7203 currentDate = reduceCurrentDate(currentDate, action); 7204 dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator); 7205 if (action.type === 'PREV' || // TODO: move this logic into DateProfileGenerator 7206 action.type === 'NEXT' || // " 7207 !rangeContainsMarker(dateProfile.currentRange, currentDate)) { 7208 currentDate = dateProfile.currentRange.start; 7209 } 7210 var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext); 7211 var eventStore = reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendarContext); 7212 var isEventsLoading = computeEventSourcesLoading(eventSources);
7212 // BAD. also called in this func in computeIsLoading 7213 var renderableEventStore = (isEventsLoading && !currentViewData.options.progressiveEventRendering) ? 7214 (state.renderableEventStore || eventStore) : // try from previous state 7215 eventStore; 7216 var _b = this.buildViewUiProps(calendarContext), eventUiSingleBase = _b.eventUiSingleBase, selectionConfig = _b.selectionConfig; // will memoize obj 7217 var eventUiBySource = this.buildEventUiBySource(eventSources); 7218 var eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource); 7219 var newState = { 7220 dynamicOptionOverrides: dynamicOptionOverrides, 7221 currentViewType: currentViewType, 7222 currentDate: currentDate, 7223 dateProfile: dateProfile, 7224 eventSources: eventSources, 7225 eventStore: eventStore, 7226 renderableEventStore: renderableEventStore, 7227 selectionConfig: selectionConfig, 7228 eventUiBases: eventUiBases, 7229 businessHours: this.parseContextBusinessHours(calendarContext), 7230 dateSelection: reduceDateSelection(state.dateSelection, action), 7231 eventSelection: reduceSelectedEvent(state.eventSelection, action), 7232 eventDrag: reduceEventDrag(state.eventDrag, action), 7233 eventResize: reduceEventResize(state.eventResize, action), 7234 }; 7235 var contextAndState = __assign(__assign({}, calendarContext), newState); 7236 for (var _i = 0, _c = optionsData.pluginHooks.reducers; _i < _c.length; _i++) { 7237 var reducer = _c[_i]; 7238 __assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value 7239 } 7240 var wasLoading = computeIsLoading(state, calendarContext); 7241 var isLoading = computeIsLoading(newState, calendarContext); 7242 // TODO: use propSetHandlers in plugin system 7243 if (!wasLoading && isLoading) { 7244 emitter.trigger('loading', true); 7245 } 7246 else if (wasLoading && !isLoading) { 7247 emitter.trigger('loading', false); 7248 } 7249 this.state = newState; 7250 if (props.onAction) { 7251 props.onAction(action); 7252 } 7253 }; 7254 CalendarDataManager.prototype.updateData = function () { 7255 var _a = this, props = _a.props, state = _a.state; 7256 var oldData = this.data; 7257 var optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi); 7258 var currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides); 7259 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); 7260 var changeHandlers = optionsData.pluginHooks.optionChangeHandlers; 7261 var oldCalendarOptions = oldData && oldData.calendarOptions; 7262 var newCalendarOptions = optionsData.calendarOptions; 7263 if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) { 7264 if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) { 7265 // hack 7266 state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data); 7267 state.eventStore = data.eventStore = rezoneEventStoreDates(data.eventStore, oldData.dateEnv, data.dateEnv); 7268 } 7269 for (var optionName in changeHandlers) { 7270 if (oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) { 7271 changeHandlers[optionName](newCalendarOptions[optionName], data); 7272 } 7273 } 7274 } 7275 if (props.onData) { 7276 props.onData(data); 7277 } 7278 }; 7279 CalendarDataManager.prototype._computeOptionsData = function (optionOverrides, dynamicOptionOverrides, calendarApi) { 7280 // TODO: blacklist options that are handled by optionChangeHandlers 7281 var _a = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, pluginHooks = _a.pluginHooks, localeDefaults = _a.localeDefaults, availableLocaleData = _a.availableLocaleData, extra = _a.extra; 7282 warnUnknownOptions(extra); 7283 var dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator); 7284 var viewSpecs = this.buildViewSpecs(pluginHooks.views, optionOverrides, dynamicOptionOverrides, localeDefaults); 7285 var theme = this.buildTheme(refinedOptions, pluginHooks); 7286 var toolbarConfig = this.parseToolbars(refinedOptions, optionOverrides, theme, viewSpecs, calendarApi); 7287 return { 7288 calendarOptions: refinedOptions, 7289 pluginHooks: pluginHooks, 7290 dateEnv: dateEnv, 7291 viewSpecs: viewSpecs, 7292 theme: theme, 7293 toolbarConfig: toolbarConfig, 7294 localeDefaults: localeDefaults, 7295 availableRawLocales: availableLocaleData.map, 7296 }; 7297 }; 7298 // always called from behind a memoizer 7299 CalendarDataManager.prototype.processRawCalendarOptions = function (optionOverrides, dynamicOptionOverrides) { 7300 var _a = mergeRawOptions([ 7301 BASE_OPTION_DEFAULTS, 7302 optionOverrides, 7303 dynamicOptionOverrides, 7304 ]), locales = _a.locales, locale = _a.locale; 7305 var availableLocaleData = this.organizeRawLocales(locales); 7306 var availableRawLocales = availableLocaleData.map; 7307 var localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options; 7308 var pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins); 7309 var refiners = this.currentCalendarOptionsRefiners = __assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners); 7310 var extra = {}; 7311 var raw = mergeRawOptions([ 7312 BASE_OPTION_DEFAULTS, 7313 localeDefaults, 7314 optionOverrides, 7315 dynamicOptionOverrides, 7316 ]);
7317 var refined = {}; 7318 var currentRaw = this.currentCalendarOptionsInput; 7319 var currentRefined = this.currentCalendarOptionsRefined; 7320 var anyChanges = false; 7321 for (var optionName in raw) { 7322 if (optionName !== 'plugins') { // because plugins is special-cased 7323 if (raw[optionName] === currentRaw[optionName] || 7324 (COMPLEX_OPTION_COMPARATORS[optionName] && 7325 (optionName in currentRaw) && 7326 COMPLEX_OPTION_COMPARATORS[optionName](currentRaw[optionName], raw[optionName]))) { 7327 refined[optionName] = currentRefined[optionName]; 7328 } 7329 else if (refiners[optionName]) { 7330 refined[optionName] = refiners[optionName](raw[optionName]); 7331 anyChanges = true; 7332 } 7333 else { 7334 extra[optionName] = currentRaw[optionName]; 7335 } 7336 } 7337 } 7338 if (anyChanges) { 7339 this.currentCalendarOptionsInput = raw; 7340 this.currentCalendarOptionsRefined = refined; 7341 } 7342 return { 7343 rawOptions: this.currentCalendarOptionsInput, 7344 refinedOptions: this.currentCalendarOptionsRefined, 7345 pluginHooks: pluginHooks, 7346 availableLocaleData: availableLocaleData, 7347 localeDefaults: localeDefaults, 7348 extra: extra, 7349 }; 7350 }; 7351 CalendarDataManager.prototype._computeCurrentViewData = function (viewType, optionsData, optionOverrides, dynamicOptionOverrides) { 7352 var viewSpec = optionsData.viewSpecs[viewType]; 7353 if (!viewSpec) { 7354 throw new Error("viewType \"" + viewType + "\" is not available. Please make sure you've loaded all neccessary plugins"); 7355 } 7356 var _a = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, extra = _a.extra; 7357 warnUnknownOptions(extra); 7358 var dateProfileGenerator = this.buildDateProfileGenerator({ 7359 dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass, 7360 duration: viewSpec.duration, 7361 durationUnit: viewSpec.durationUnit, 7362 usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime, 7363 dateEnv: optionsData.dateEnv, 7364 calendarApi: this.props.calendarApi, 7365 slotMinTime: refinedOptions.slotMinTime, 7366 slotMaxTime: refinedOptions.slotMaxTime, 7367 showNonCurrentDates: refinedOptions.showNonCurrentDates, 7368 dayCount: refinedOptions.dayCount, 7369 dateAlignment: refinedOptions.dateAlignment, 7370 dateIncrement: refinedOptions.dateIncrement, 7371 hiddenDays: refinedOptions.hiddenDays, 7372 weekends: refinedOptions.weekends, 7373 nowInput: refinedOptions.now, 7374 validRangeInput: refinedOptions.validRange, 7375 visibleRangeInput: refinedOptions.visibleRange, 7376 monthMode: refinedOptions.monthMode, 7377 fixedWeekCount: refinedOptions.fixedWeekCount, 7378 }); 7379 var viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv); 7380 return { viewSpec: viewSpec, options: refinedOptions, dateProfileGenerator: dateProfileGenerator, viewApi: viewApi }; 7381 }; 7382 CalendarDataManager.prototype.processRawViewOptions = function (viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) { 7383 var raw = mergeRawOptions([ 7384 BASE_OPTION_DEFAULTS, 7385 viewSpec.optionDefaults, 7386 localeDefaults, 7387 optionOverrides, 7388 viewSpec.optionOverrides, 7389 dynamicOptionOverrides, 7390 ]); 7391 var refiners = __assign(__assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), VIEW_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
7392 var refined = {}; 7393 var currentRaw = this.currentViewOptionsInput; 7394 var currentRefined = this.currentViewOptionsRefined; 7395 var anyChanges = false; 7396 var extra = {}; 7397 for (var optionName in raw) { 7398 if (raw[optionName] === currentRaw[optionName]) { 7399 refined[optionName] = currentRefined[optionName]; 7400 } 7401 else { 7402 if (raw[optionName] === this.currentCalendarOptionsInput[optionName]) { 7403 if (optionName in this.currentCalendarOptionsRefined) { // might be an "extra" prop 7404 refined[optionName] = this.currentCalendarOptionsRefined[optionName]; 7405 } 7406 } 7407 else if (refiners[optionName]) { 7408 refined[optionName] = refiners[optionName](raw[optionName]); 7409 } 7410 else { 7411 extra[optionName] = raw[optionName]; 7412 } 7413 anyChanges = true; 7414 } 7415 } 7416 if (anyChanges) { 7417 this.currentViewOptionsInput = raw; 7418 this.currentViewOptionsRefined = refined; 7419 } 7420 return { 7421 rawOptions: this.currentViewOptionsInput, 7422 refinedOptions: this.currentViewOptionsRefined, 7423 extra: extra, 7424 }; 7425 }; 7426 return CalendarDataManager; 7427 }()); 7428 function buildDateEnv(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) { 7429 var locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map); 7430 return new DateEnv({ 7431 calendarSystem: 'gregory', 7432 timeZone: timeZone, 7433 namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl, 7434 locale: locale, 7435 weekNumberCalculation: weekNumberCalculation, 7436 firstDay: firstDay, 7437 weekText: weekText, 7438 cmdFormatter: pluginHooks.cmdFormatter, 7439 defaultSeparator: defaultSeparator, 7440 }); 7441 } 7442 function buildTheme(options, pluginHooks) { 7443 var ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme; 7444 return new ThemeClass(options); 7445 } 7446 function buildDateProfileGenerator(props) { 7447 var DateProfileGeneratorClass = props.dateProfileGeneratorClass || DateProfileGenerator; 7448 return new DateProfileGeneratorClass(props); 7449 } 7450 function buildViewApi(type, getCurrentData, dateEnv) { 7451 return new ViewApi(type, getCurrentData, dateEnv); 7452 } 7453 function buildEventUiBySource(eventSources) { 7454 return mapHash(eventSources, function (eventSource) { return eventSource.ui; }); 7455 } 7456 function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) { 7457 var eventUiBases = { '': eventUiSingleBase }; 7458 for (var defId in eventDefs) { 7459 var def = eventDefs[defId]; 7460 if (def.sourceId && eventUiBySource[def.sourceId]) { 7461 eventUiBases[defId] = eventUiBySource[def.sourceId]; 7462 } 7463 } 7464 return eventUiBases; 7465 } 7466 function buildViewUiProps(calendarContext) { 7467 var options = calendarContext.options; 7468 return { 7469 eventUiSingleBase: createEventUi({ 7470 display: options.eventDisplay, 7471 editable: options.editable, 7472 startEditable: options.eventStartEditable, 7473 durationEditable: options.eventDurationEditable, 7474 constraint: options.eventConstraint, 7475 overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined, 7476 allow: options.eventAllow, 7477 backgroundColor: options.eventBackgroundColor, 7478 borderColor: options.eventBorderColor, 7479 textColor: options.eventTextColor, 7480 color: options.eventColor, 7481 // classNames: options.eventClassNames // render hook will handle this 7482 }, calendarContext), 7483 selectionConfig: createEventUi({ 7484 constraint: options.selectConstraint, 7485 overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined, 7486 allow: options.selectAllow, 7487 }, calendarContext), 7488 }; 7489 } 7490 function computeIsLoading(state, context) { 7491 for (var _i = 0, _a = context.pluginHooks.isLoadingFuncs; _i < _a.length; _i++) { 7492 var isLoadingFunc = _a[_i]; 7493 if (isLoadingFunc(state)) { 7494 return true; 7495 } 7496 } 7497 return false;
7498 } 7499 function parseContextBusinessHours(calendarContext) { 7500 return parseBusinessHours(calendarContext.options.businessHours, calendarContext); 7501 } 7502 function warnUnknownOptions(options, viewName) { 7503 for (var optionName in options) { 7504 console.warn("Unknown option '" + optionName + "'" + 7505 (viewName ? " for view '" + viewName + "'" : '')); 7506 } 7507 } 7508 7509 // TODO: move this to react plugin? 7510 var CalendarDataProvider = /** @class */ (function (_super) { 7511 __extends(CalendarDataProvider, _super); 7512 function CalendarDataProvider(props) { 7513 var _this = _super.call(this, props) || this; 7514 _this.handleData = function (data) { 7515 if (!_this.dataManager) { // still within initial run, before assignment in constructor 7516 // eslint-disable-next-line react/no-direct-mutation-state 7517 _this.state = data; // can't use setState yet 7518 } 7519 else { 7520 _this.setState(data); 7521 } 7522 }; 7523 _this.dataManager = new CalendarDataManager({ 7524 optionOverrides: props.optionOverrides, 7525 calendarApi: props.calendarApi, 7526 onData: _this.handleData, 7527 }); 7528 return _this; 7529 } 7530 CalendarDataProvider.prototype.render = function () { 7531 return this.props.children(this.state); 7532 }; 7533 CalendarDataProvider.prototype.componentDidUpdate = function (prevProps) { 7534 var newOptionOverrides = this.props.optionOverrides; 7535 if (newOptionOverrides !== prevProps.optionOverrides) { // prevent recursive handleData 7536 this.dataManager.resetOptions(newOptionOverrides); 7537 } 7538 }; 7539 return CalendarDataProvider; 7540 }(Component)); 7541 7542 // HELPERS 7543 /* 7544 if nextDayThreshold is specified, slicing is done in an all-day fashion. 7545 you can get nextDayThreshold from context.nextDayThreshold 7546 */ 7547 function sliceEvents(props, allDay) { 7548 return sliceEventStore(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg; 7549 } 7550 7551 var NamedTimeZoneImpl = /** @class */ (function () { 7552 function NamedTimeZoneImpl(timeZoneName) { 7553 this.timeZoneName = timeZoneName; 7554 } 7555 return NamedTimeZoneImpl; 7556 }()); 7557 7558 var SegHierarchy = /** @class */ (function () { 7559 function SegHierarchy() { 7560 // settings 7561 this.strictOrder = false; 7562 this.allowReslicing = false; 7563 this.maxCoord = -1; // -1 means no max 7564 this.maxStackCnt = -1; // -1 means no max 7565 this.levelCoords = []; // ordered 7566 this.entriesByLevel = []; // parallel with levelCoords 7567 this.stackCnts = {}; // TODO: use better technique!? 7568 } 7569 SegHierarchy.prototype.addSegs = function (inputs) { 7570 var hiddenEntries = []; 7571 for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) { 7572 var input = inputs_1[_i]; 7573 this.insertEntry(input, hiddenEntries); 7574 } 7575 return hiddenEntries; 7576 }; 7577 SegHierarchy.prototype.insertEntry = function (entry, hiddenEntries) { 7578 var insertion = this.findInsertion(entry); 7579 if (this.isInsertionValid(insertion, entry)) { 7580 this.insertEntryAt(entry, insertion); 7581 return 1; 7582 } 7583 return this.handleInvalidInsertion(insertion, entry, hiddenEntries); 7584 }; 7585 SegHierarchy.prototype.isInsertionValid = function (insertion, entry) { 7586 return (this.maxCoord === -1 || insertion.levelCoord + entry.thickness <= this.maxCoord) && 7587 (this.maxStackCnt === -1 || insertion.stackCnt < this.maxStackCnt); 7588 }; 7589 // returns number of new entries inserted 7590 SegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) {
7591 if (this.allowReslicing && insertion.touchingEntry) { 7592 return this.splitEntry(entry, insertion.touchingEntry, hiddenEntries); 7593 } 7594 hiddenEntries.push(entry); 7595 return 0; 7596 }; 7597 SegHierarchy.prototype.splitEntry = function (entry, barrier, hiddenEntries) { 7598 var partCnt = 0; 7599 var splitHiddenEntries = []; 7600 var entrySpan = entry.span; 7601 var barrierSpan = barrier.span; 7602 if (entrySpan.start < barrierSpan.start) { 7603 partCnt += this.insertEntry({ 7604 index: entry.index, 7605 thickness: entry.thickness, 7606 span: { start: entrySpan.start, end: barrierSpan.start }, 7607 }, splitHiddenEntries); 7608 } 7609 if (entrySpan.end > barrierSpan.end) { 7610 partCnt += this.insertEntry({ 7611 index: entry.index, 7612 thickness: entry.thickness, 7613 span: { start: barrierSpan.end, end: entrySpan.end }, 7614 }, splitHiddenEntries); 7615 } 7616 if (partCnt) { 7617 hiddenEntries.push.apply(hiddenEntries, __spreadArray([{ 7618 index: entry.index, 7619 thickness: entry.thickness, 7620 span: intersectSpans(barrierSpan, entrySpan), // guaranteed to intersect 7621 }], splitHiddenEntries)); 7622 return partCnt; 7623 } 7624 hiddenEntries.push(entry); 7625 return 0; 7626 }; 7627 SegHierarchy.prototype.insertEntryAt = function (entry, insertion) { 7628 var _a = this, entriesByLevel = _a.entriesByLevel, levelCoords = _a.levelCoords; 7629 if (insertion.lateral === -1) { 7630 // create a new level 7631 insertAt(levelCoords, insertion.level, insertion.levelCoord); 7632 insertAt(entriesByLevel, insertion.level, [entry]); 7633 } 7634 else { 7635 // insert into existing level 7636 insertAt(entriesByLevel[insertion.level], insertion.lateral, entry); 7637 } 7638 this.stackCnts[buildEntryKey(entry)] = insertion.stackCnt; 7639 }; 7640 SegHierarchy.prototype.findInsertion = function (newEntry) { 7641 var _a = this, levelCoords = _a.levelCoords, entriesByLevel = _a.entriesByLevel, strictOrder = _a.strictOrder, stackCnts = _a.stackCnts; 7642 var levelCnt = levelCoords.length; 7643 var candidateCoord = 0; 7644 var touchingLevel = -1; 7645 var touchingLateral = -1; 7646 var touchingEntry = null; 7647 var stackCnt = 0; 7648 for (var trackingLevel = 0; trackingLevel < levelCnt; trackingLevel += 1) { 7649 var trackingCoord = levelCoords[trackingLevel]; 7650 // if the current level is past the placed entry, we have found a good empty space and can stop. 7651 // if strictOrder, keep finding more lateral intersections. 7652 if (!strictOrder && trackingCoord >= candidateCoord + newEntry.thickness) { 7653 break; 7654 } 7655 var trackingEntries = entriesByLevel[trackingLevel]; 7656 var trackingEntry = void 0; 7657 var searchRes = binarySearch(trackingEntries, newEntry.span.start, getEntrySpanEnd); // find first entry after newEntry's end 7658 var lateralIndex = searchRes[0] + searchRes[1]; // if exact match (which doesn't collide), go to next one 7659 while ( // loop through entries that horizontally intersect 7660 (trackingEntry = trackingEntries[lateralIndex]) && // but not past the whole entry list 7661 trackingEntry.span.start < newEntry.span.end // and not entirely past newEntry 7662 ) { 7663 var trackingEntryBottom = trackingCoord + trackingEntry.thickness; 7664 // intersects into the top of the candidate? 7665 if (trackingEntryBottom > candidateCoord) { 7666 candidateCoord = trackingEntryBottom; 7667 touchingEntry = trackingEntry; 7668 touchingLevel = trackingLevel; 7669 touchingLateral = lateralIndex; 7670 }
7671 // butts up against top of candidate? (will happen if just intersected as well) 7672 if (trackingEntryBottom === candidateCoord) { 7673 // accumulate the highest possible stackCnt of the trackingEntries that butt up 7674 stackCnt = Math.max(stackCnt, stackCnts[buildEntryKey(trackingEntry)] + 1); 7675 } 7676 lateralIndex += 1; 7677 } 7678 } 7679 // the destination level will be after touchingEntry's level. find it 7680 var destLevel = 0; 7681 if (touchingEntry) { 7682 destLevel = touchingLevel + 1; 7683 while (destLevel < levelCnt && levelCoords[destLevel] < candidateCoord) { 7684 destLevel += 1; 7685 } 7686 } 7687 // if adding to an existing level, find where to insert 7688 var destLateral = -1; 7689 if (destLevel < levelCnt && levelCoords[destLevel] === candidateCoord) { 7690 destLateral = binarySearch(entriesByLevel[destLevel], newEntry.span.end, getEntrySpanEnd)[0]; 7691 } 7692 return { 7693 touchingLevel: touchingLevel, 7694 touchingLateral: touchingLateral, 7695 touchingEntry: touchingEntry, 7696 stackCnt: stackCnt, 7697 levelCoord: candidateCoord, 7698 level: destLevel, 7699 lateral: destLateral, 7700 }; 7701 }; 7702 // sorted by levelCoord (lowest to highest) 7703 SegHierarchy.prototype.toRects = function () { 7704 var _a = this, entriesByLevel = _a.entriesByLevel, levelCoords = _a.levelCoords; 7705 var levelCnt = entriesByLevel.length; 7706 var rects = []; 7707 for (var level = 0; level < levelCnt; level += 1) { 7708 var entries = entriesByLevel[level]; 7709 var levelCoord = levelCoords[level]; 7710 for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { 7711 var entry = entries_1[_i]; 7712 rects.push(__assign(__assign({}, entry), { levelCoord: levelCoord })); 7713 } 7714 } 7715 return rects; 7716 }; 7717 return SegHierarchy; 7718 }()); 7719 function getEntrySpanEnd(entry) { 7720 return entry.span.end; 7721 } 7722 function buildEntryKey(entry) { 7723 return entry.index + ':' + entry.span.start; 7724 } 7725 // returns groups with entries sorted by input order 7726 function groupIntersectingEntries(entries) { 7727 var merges = []; 7728 for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { 7729 var entry = entries_2[_i]; 7730 var filteredMerges = []; 7731 var hungryMerge = { 7732 span: entry.span, 7733 entries: [entry], 7734 }; 7735 for (var _a = 0, merges_1 = merges; _a < merges_1.length; _a++) { 7736 var merge = merges_1[_a]; 7737 if (intersectSpans(merge.span, hungryMerge.span)) { 7738 hungryMerge = { 7739 entries: merge.entries.concat(hungryMerge.entries), 7740 span: joinSpans(merge.span, hungryMerge.span), 7741 }; 7742 } 7743 else { 7744 filteredMerges.push(merge); 7745 } 7746 } 7747 filteredMerges.push(hungryMerge); 7748 merges = filteredMerges; 7749 } 7750 return merges; 7751 } 7752 function joinSpans(span0, span1) { 7753 return { 7754 start: Math.min(span0.start, span1.start), 7755 end: Math.max(span0.end, span1.end), 7756 }; 7757 } 7758 function intersectSpans(span0, span1) { 7759 var start = Math.max(span0.start, span1.start); 7760 var end = Math.min(span0.end, span1.end); 7761 if (start < end) { 7762 return { start: start, end: end }; 7763 } 7764 return null; 7765 } 7766 // general util 7767 // --------------------------------------------------------------------------------------------------------------------- 7768 function insertAt(arr, index, item) { 7769 arr.splice(index, 0, item); 7770 }
7771 function binarySearch(a, searchVal, getItemVal) { 7772 var startIndex = 0; 7773 var endIndex = a.length; // exclusive 7774 if (!endIndex || searchVal < getItemVal(a[startIndex])) { // no items OR before first item 7775 return [0, 0]; 7776 } 7777 if (searchVal > getItemVal(a[endIndex - 1])) { // after last item 7778 return [endIndex, 0]; 7779 } 7780 while (startIndex < endIndex) { 7781 var middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2); 7782 var middleVal = getItemVal(a[middleIndex]); 7783 if (searchVal < middleVal) { 7784 endIndex = middleIndex; 7785 } 7786 else if (searchVal > middleVal) { 7787 startIndex = middleIndex + 1; 7788 } 7789 else { // equal! 7790 return [middleIndex, 1]; 7791 } 7792 } 7793 return [startIndex, 0]; 7794 } 7795 7796 var Interaction = /** @class */ (function () { 7797 function Interaction(settings) { 7798 this.component = settings.component; 7799 this.isHitComboAllowed = settings.isHitComboAllowed || null; 7800 } 7801 Interaction.prototype.destroy = function () { 7802 }; 7803 return Interaction; 7804 }()); 7805 function parseInteractionSettings(component, input) { 7806 return { 7807 component: component, 7808 el: input.el, 7809 useEventCenter: input.useEventCenter != null ? input.useEventCenter : true, 7810 isHitComboAllowed: input.isHitComboAllowed || null, 7811 }; 7812 } 7813 function interactionSettingsToStore(settings) { 7814 var _a; 7815 return _a = {}, 7816 _a[settings.component.uid] = settings, 7817 _a; 7818 } 7819 // global state 7820 var interactionSettingsStore = {}; 7821 7822 /* 7823 An abstraction for a dragging interaction originating on an event. 7824 Does higher-level things than PointerDragger, such as possibly: 7825 - a "mirror" that moves with the pointer 7826 - a minimum number of pixels or other criteria for a true drag to begin 7827 7828 subclasses must emit: 7829 - pointerdown 7830 - dragstart 7831 - dragmove 7832 - pointerup 7833 - dragend 7834 */ 7835 var ElementDragging = /** @class */ (function () { 7836 function ElementDragging(el, selector) { 7837 this.emitter = new Emitter(); 7838 } 7839 ElementDragging.prototype.destroy = function () { 7840 }; 7841 ElementDragging.prototype.setMirrorIsVisible = function (bool) { 7842 // optional if subclass doesn't want to support a mirror 7843 }; 7844 ElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 7845 // optional if subclass doesn't want to support a mirror 7846 }; 7847 ElementDragging.prototype.setAutoScrollEnabled = function (bool) { 7848 // optional 7849 }; 7850 return ElementDragging; 7851 }()); 7852 7853 // TODO: get rid of this in favor of options system, 7854 // tho it's really easy to access this globally rather than pass thru options. 7855 var config = {}; 7856 7857 /* 7858 Information about what will happen when an external element is dragged-and-dropped 7859 onto a calendar. Contains information for creating an event. 7860 */ 7861 var DRAG_META_REFINERS = { 7862 startTime: createDuration, 7863 duration: createDuration, 7864 create: Boolean, 7865 sourceId: String, 7866 }; 7867 function parseDragMeta(raw) { 7868 var _a = refineProps(raw, DRAG_META_REFINERS), refined = _a.refined, extra = _a.extra; 7869 return { 7870 startTime: refined.startTime || null, 7871 duration: refined.duration || null, 7872 create: refined.create != null ? refined.create : true, 7873 sourceId: refined.sourceId, 7874 leftoverProps: extra, 7875 }; 7876 } 7877 7878 var ToolbarSection = /** @class */ (function (_super) { 7879 __extends(ToolbarSection, _super); 7880 function ToolbarSection() { 7881 return _super !== null && _super.apply(this, arguments) || this; 7882 } 7883 ToolbarSection.prototype.render = function () { 7884 var _this = this; 7885 var children = this.props.widgetGroups.map(function (widgetGroup) { return _this.renderWidgetGroup(widgetGroup); }); 7886 return createElement.apply(void 0, __spreadArray(['div', { className: 'fc-toolbar-chunk' }], children)); 7887 }; 7888 ToolbarSection.prototype.renderWidgetGroup = function (widgetGroup) { 7889 var props = this.props; 7890 var theme = this.context.theme; 7891 var children = []; 7892 var isOnlyButtons = true; 7893 for (var _i = 0, widgetGroup_1 = widgetGroup; _i < widgetGroup_1.length; _i++) { 7894 var widget = widgetGroup_1[_i]; 7895 var buttonName = widget.buttonName, buttonClick = widget.buttonClick, buttonText = widget.buttonText, buttonIcon = widget.buttonIcon, buttonHint = widget.buttonHint; 7896 if (buttonName === 'title') { 7897 isOnlyButtons = false;
7898 children.push(createElement("h2", { className: "fc-toolbar-title", id: props.titleId }, props.title)); 7899 } 7900 else { 7901 var isPressed = buttonName === props.activeButton; 7902 var isDisabled = (!props.isTodayEnabled && buttonName === 'today') || 7903 (!props.isPrevEnabled && buttonName === 'prev') || 7904 (!props.isNextEnabled && buttonName === 'next'); 7905 var buttonClasses = ["fc-" + buttonName + "-button", theme.getClass('button')]; 7906 if (isPressed) { 7907 buttonClasses.push(theme.getClass('buttonActive')); 7908 } 7909 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 }) : ''))); 7910 } 7911 } 7912 if (children.length > 1) { 7913 var groupClassName = (isOnlyButtons && theme.getClass('buttonGroup')) || ''; 7914 return createElement.apply(void 0, __spreadArray(['div', { className: groupClassName }], children)); 7915 } 7916 return children[0]; 7917 }; 7918 return ToolbarSection; 7919 }(BaseComponent)); 7920 7921 var Toolbar = /** @class */ (function (_super) { 7922 __extends(Toolbar, _super); 7923 function Toolbar() { 7924 return _super !== null && _super.apply(this, arguments) || this; 7925 } 7926 Toolbar.prototype.render = function () { 7927 var _a = this.props, model = _a.model, extraClassName = _a.extraClassName; 7928 var forceLtr = false; 7929 var startContent; 7930 var endContent; 7931 var sectionWidgets = model.sectionWidgets; 7932 var centerContent = sectionWidgets.center; 7933 if (sectionWidgets.left) { 7934 forceLtr = true; 7935 startContent = sectionWidgets.left; 7936 } 7937 else { 7938 startContent = sectionWidgets.start; 7939 } 7940 if (sectionWidgets.right) { 7941 forceLtr = true; 7942 endContent = sectionWidgets.right; 7943 } 7944 else { 7945 endContent = sectionWidgets.end; 7946 } 7947 var classNames = [ 7948 extraClassName || '', 7949 'fc-toolbar', 7950 forceLtr ? 'fc-toolbar-ltr' : '', 7951 ]; 7952 return (createElement("div", { className: classNames.join(' ') }, 7953 this.renderSection('start', startContent || []), 7954 this.renderSection('center', centerContent || []), 7955 this.renderSection('end', endContent || []))); 7956 }; 7957 Toolbar.prototype.renderSection = function (key, widgetGroups) { 7958 var props = this.props; 7959 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 })); 7960 }; 7961 return Toolbar; 7962 }(BaseComponent)); 7963 7964 // TODO: do function component? 7965 var ViewContainer = /** @class */ (function (_super) { 7966 __extends(ViewContainer, _super); 7967 function ViewContainer() { 7968 var _this = _super !== null && _super.apply(this, arguments) || this; 7969 _this.state = { 7970 availableWidth: null, 7971 }; 7972 _this.handleEl = function (el) { 7973 _this.el = el; 7974 setRef(_this.props.elRef, el); 7975 _this.updateAvailableWidth(); 7976 }; 7977 _this.handleResize = function () { 7978 _this.updateAvailableWidth(); 7979 }; 7980 return _this; 7981 } 7982 ViewContainer.prototype.render = function () { 7983 var _a = this, props = _a.props, state = _a.state; 7984 var aspectRatio = props.aspectRatio; 7985 var classNames = [ 7986 'fc-view-harness', 7987 (aspectRatio || props.liquid || props.height) 7988 ? 'fc-view-harness-active' // harness controls the height
7989 : 'fc-view-harness-passive', // let the view do the height 7990 ]; 7991 var height = ''; 7992 var paddingBottom = ''; 7993 if (aspectRatio) { 7994 if (state.availableWidth !== null) { 7995 height = state.availableWidth / aspectRatio; 7996 } 7997 else { 7998 // while waiting to know availableWidth, we can't set height to *zero* 7999 // because will cause lots of unnecessary scrollbars within scrollgrid. 8000 // BETTER: don't start rendering ANYTHING yet until we know container width 8001 // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606) 8002 paddingBottom = (1 / aspectRatio) * 100 + "%"; 8003 } 8004 } 8005 else { 8006 height = props.height || ''; 8007 } 8008 return (createElement("div", { "aria-labelledby": props.labeledById, ref: this.handleEl, className: classNames.join(' '), style: { height: height, paddingBottom: paddingBottom } }, props.children)); 8009 }; 8010 ViewContainer.prototype.componentDidMount = function () { 8011 this.context.addResizeHandler(this.handleResize); 8012 }; 8013 ViewContainer.prototype.componentWillUnmount = function () { 8014 this.context.removeResizeHandler(this.handleResize); 8015 }; 8016 ViewContainer.prototype.updateAvailableWidth = function () { 8017 if (this.el && // needed. but why? 8018 this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth 8019 ) { 8020 this.setState({ availableWidth: this.el.offsetWidth }); 8021 } 8022 }; 8023 return ViewContainer; 8024 }(BaseComponent)); 8025 8026 /* 8027 Detects when the user clicks on an event within a DateComponent 8028 */ 8029 var EventClicking = /** @class */ (function (_super) { 8030 __extends(EventClicking, _super); 8031 function EventClicking(settings) { 8032 var _this = _super.call(this, settings) || this; 8033 _this.handleSegClick = function (ev, segEl) { 8034 var component = _this.component; 8035 var context = component.context; 8036 var seg = getElSeg(segEl); 8037 if (seg && // might be the <div> surrounding the more link 8038 component.isValidSegDownEl(ev.target)) { 8039 // our way to simulate a link click for elements that can't be <a> tags 8040 // grab before trigger fired in case trigger trashes DOM thru rerendering 8041 var hasUrlContainer = elementClosest(ev.target, '.fc-event-forced-url'); 8042 var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : ''; 8043 context.emitter.trigger('eventClick', { 8044 el: segEl, 8045 event: new EventApi(component.context, seg.eventRange.def, seg.eventRange.instance), 8046 jsEvent: ev, 8047 view: context.viewApi, 8048 }); 8049 if (url && !ev.defaultPrevented) { 8050 window.location.href = url; 8051 } 8052 } 8053 }; 8054 _this.destroy = listenBySelector(settings.el, 'click', '.fc-event', // on both fg and bg events 8055 _this.handleSegClick); 8056 return _this; 8057 } 8058 return EventClicking; 8059 }(Interaction)); 8060 8061 /* 8062 Triggers events and adds/removes core classNames when the user's pointer 8063 enters/leaves event-elements of a component. 8064 */ 8065 var EventHovering = /** @class */ (function (_super) { 8066 __extends(EventHovering, _super); 8067 function EventHovering(settings) { 8068 var _this = _super.call(this, settings) || this; 8069 // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it 8070 _this.handleEventElRemove = function (el) { 8071 if (el === _this.currentSegEl) { 8072 _this.handleSegLeave(null, _this.currentSegEl); 8073 } 8074 }; 8075 _this.handleSegEnter = function (ev, segEl) { 8076 if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper 8077 _this.currentSegEl = segEl; 8078 _this.triggerEvent('eventMouseEnter', ev, segEl); 8079 } 8080 }; 8081 _this.handleSegLeave = function (ev, segEl) { 8082 if (_this.currentSegEl) { 8083 _this.currentSegEl = null; 8084 _this.triggerEvent('eventMouseLeave', ev, segEl); 8085 } 8086 }; 8087 _this.removeHoverListeners = listenToHoverBySelector(settings.el, '.fc-event', // on both fg and bg events 8088 _this.handleSegEnter, _this.handleSegLeave); 8089 return _this; 8090 } 8091 EventHovering.prototype.destroy = function () { 8092 this.removeHoverListeners(); 8093 }; 8094 EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) { 8095 var component = this.component; 8096 var context = component.context; 8097 var seg = getElSeg(segEl); 8098 if (!ev || component.isValidSegDownEl(ev.target)) { 8099 context.emitter.trigger(publicEvName, { 8100 el: segEl, 8101 event: new EventApi(context, seg.eventRange.def, seg.eventRange.instance), 8102 jsEvent: ev, 8103 view: context.viewApi, 8104 }); 8105 } 8106 }; 8107 return EventHovering; 8108 }(Interaction)); 8109 8110 var CalendarContent = /** @class */ (function (_super) { 8111 __extends(CalendarContent, _super); 8112 function CalendarContent() { 8113 var _this = _super !== null && _super.apply(this, arguments) || this; 8114 _this.buildViewContext = memoize(buildViewContext); 8115 _this.buildViewPropTransformers = memoize(buildViewPropTransformers); 8116 _this.buildToolbarProps = memoize(buildToolbarProps); 8117 _this.headerRef = createRef(); 8118 _this.footerRef = createRef(); 8119 _this.interactionsStore = {}; 8120 // eslint-disable-next-line 8121 _this.state = { 8122 viewLabelId: getUniqueDomId(), 8123 }; 8124 // Component Registration 8125 // ----------------------------------------------------------------------------------------------------------------- 8126 _this.registerInteractiveComponent = function (component, settingsInput) { 8127 var settings = parseInteractionSettings(component, settingsInput); 8128 var DEFAULT_INTERACTIONS = [ 8129 EventClicking, 8130 EventHovering, 8131 ]; 8132 var interactionClasses = DEFAULT_INTERACTIONS.concat(_this.props.pluginHooks.componentInteractions); 8133 var interactions = interactionClasses.map(function (TheInteractionClass) { return new TheInteractionClass(settings); }); 8134 _this.interactionsStore[component.uid] = interactions; 8135 interactionSettingsStore[component.uid] = settings; 8136 }; 8137 _this.unregisterInteractiveComponent = function (component) { 8138 for (var _i = 0, _a = _this.interactionsStore[component.uid]; _i < _a.length; _i++) { 8139 var listener = _a[_i]; 8140 listener.destroy(); 8141 } 8142 delete _this.interactionsStore[component.uid]; 8143 delete interactionSettingsStore[component.uid]; 8144 }; 8145 // Resizing 8146 // ----------------------------------------------------------------------------------------------------------------- 8147 _this.resizeRunner = new DelayedRunner(function () { 8148 _this.props.emitter.trigger('_resize', true); // should window resizes be considered "forced" ? 8149 _this.props.emitter.trigger('windowResize', { view: _this.props.viewApi }); 8150 }); 8151 _this.handleWindowResize = function (ev) { 8152 var options = _this.props.options; 8153 if (options.handleWindowResize && 8154 ev.target === window // avoid jqui events 8155 ) { 8156 _this.resizeRunner.request(options.windowResizeDelay); 8157 } 8158 }; 8159 return _this; 8160 } 8161 /* 8162 renders INSIDE of an outer div 8163 */ 8164 CalendarContent.prototype.render = function () { 8165 var props = this.props; 8166 var toolbarConfig = props.toolbarConfig, options = props.options; 8167 var toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, getNow(props.options.now, props.dateEnv), // TODO: use NowTimer???? 8168 props.viewTitle); 8169 var viewVGrow = false;
8170 var viewHeight = ''; 8171 var viewAspectRatio; 8172 if (props.isHeightAuto || props.forPrint) { 8173 viewHeight = ''; 8174 } 8175 else if (options.height != null) { 8176 viewVGrow = true; 8177 } 8178 else if (options.contentHeight != null) { 8179 viewHeight = options.contentHeight; 8180 } 8181 else { 8182 viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall 8183 } 8184 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); 8185 var viewLabelId = (toolbarConfig.header && toolbarConfig.header.hasTitle) 8186 ? this.state.viewLabelId 8187 : ''; 8188 return (createElement(ViewContextType.Provider, { value: viewContext }, 8189 toolbarConfig.header && (createElement(Toolbar, __assign({ ref: this.headerRef, extraClassName: "fc-header-toolbar", model: toolbarConfig.header, titleId: viewLabelId }, toolbarProps))), 8190 createElement(ViewContainer, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, labeledById: viewLabelId }, 8191 this.renderView(props), 8192 this.buildAppendContent()), 8193 toolbarConfig.footer && (createElement(Toolbar, __assign({ ref: this.footerRef, extraClassName: "fc-footer-toolbar", model: toolbarConfig.footer, titleId: "" }, toolbarProps))))); 8194 }; 8195 CalendarContent.prototype.componentDidMount = function () { 8196 var props = this.props; 8197 this.calendarInteractions = props.pluginHooks.calendarInteractions 8198 .map(function (CalendarInteractionClass) { return new CalendarInteractionClass(props); }); 8199 window.addEventListener('resize', this.handleWindowResize); 8200 var propSetHandlers = props.pluginHooks.propSetHandlers; 8201 for (var propName in propSetHandlers) { 8202 propSetHandlers[propName](props[propName], props); 8203 } 8204 }; 8205 CalendarContent.prototype.componentDidUpdate = function (prevProps) { 8206 var props = this.props; 8207 var propSetHandlers = props.pluginHooks.propSetHandlers; 8208 for (var propName in propSetHandlers) { 8209 if (props[propName] !== prevProps[propName]) { 8210 propSetHandlers[propName](props[propName], props); 8211 } 8212 } 8213 }; 8214 CalendarContent.prototype.componentWillUnmount = function () { 8215 window.removeEventListener('resize', this.handleWindowResize); 8216 this.resizeRunner.clear(); 8217 for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) { 8218 var interaction = _a[_i]; 8219 interaction.destroy(); 8220 } 8221 this.props.emitter.trigger('_unmount'); 8222 }; 8223 CalendarContent.prototype.buildAppendContent = function () { 8224 var props = this.props; 8225 var children = props.pluginHooks.viewContainerAppends.map(function (buildAppendContent) { return buildAppendContent(props); }); 8226 return createElement.apply(void 0, __spreadArray([Fragment, {}], children)); 8227 }; 8228 CalendarContent.prototype.renderView = function (props) { 8229 var pluginHooks = props.pluginHooks; 8230 var viewSpec = props.viewSpec; 8231 var viewProps = { 8232 dateProfile: props.dateProfile, 8233 businessHours: props.businessHours, 8234 eventStore: props.renderableEventStore, 8235 eventUiBases: props.eventUiBases, 8236 dateSelection: props.dateSelection, 8237 eventSelection: props.eventSelection, 8238 eventDrag: props.eventDrag, 8239 eventResize: props.eventResize, 8240 isHeightAuto: props.isHeightAuto, 8241 forPrint: props.forPrint, 8242 }; 8243 var transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers); 8244 for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) { 8245 var transformer = transformers_1[_i]; 8246 __assign(viewProps, transformer.transform(viewProps, props)); 8247 } 8248 var ViewComponent = viewSpec.component; 8249 return (createElement(ViewComponent, __assign({}, viewProps))); 8250 }; 8251 return CalendarContent; 8252 }(PureComponent)); 8253 function buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) { 8254 // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid 8255 var todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason 8256 var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false); 8257 var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false); 8258 return { 8259 title: title, 8260 activeButton: viewSpec.type, 8261 navUnit: viewSpec.singleUnit, 8262 isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now), 8263 isPrevEnabled: prevInfo.isValid, 8264 isNextEnabled: nextInfo.isValid, 8265 }; 8266 } 8267 // Plugin 8268 // ----------------------------------------------------------------------------------------------------------------- 8269 function buildViewPropTransformers(theClasses) { 8270 return theClasses.map(function (TheClass) { return new TheClass(); }); 8271 } 8272 8273 var CalendarRoot = /** @class */ (function (_super) { 8274 __extends(CalendarRoot, _super); 8275 function CalendarRoot() { 8276 var _this = _super !== null && _super.apply(this, arguments) || this; 8277 _this.state = { 8278 forPrint: false, 8279 }; 8280 _this.handleBeforePrint = function () { 8281 _this.setState({ forPrint: true }); 8282 }; 8283 _this.handleAfterPrint = function () { 8284 _this.setState({ forPrint: false }); 8285 }; 8286 return _this; 8287 } 8288 CalendarRoot.prototype.render = function () { 8289 var props = this.props; 8290 var options = props.options; 8291 var forPrint = this.state.forPrint; 8292 var isHeightAuto = forPrint || options.height === 'auto' || options.contentHeight === 'auto'; 8293 var height = (!isHeightAuto && options.height != null) ? options.height : ''; 8294 var classNames = [ 8295 'fc', 8296 forPrint ? 'fc-media-print' : 'fc-media-screen', 8297 "fc-direction-" + options.direction, 8298 props.theme.getClass('root'), 8299 ]; 8300 if (!getCanVGrowWithinCell()) { 8301 classNames.push('fc-liquid-hack'); 8302 } 8303 return props.children(classNames, height, isHeightAuto, forPrint); 8304 }; 8305 CalendarRoot.prototype.componentDidMount = function () { 8306 var emitter = this.props.emitter; 8307 emitter.on('_beforeprint', this.handleBeforePrint); 8308 emitter.on('_afterprint', this.handleAfterPrint); 8309 }; 8310 CalendarRoot.prototype.componentWillUnmount = function () { 8311 var emitter = this.props.emitter; 8312 emitter.off('_beforeprint', this.handleBeforePrint); 8313 emitter.off('_afterprint', this.handleAfterPrint); 8314 }; 8315 return CalendarRoot; 8316 }(BaseComponent)); 8317 8318 // Computes a default column header formatting string if `colFormat` is not explicitly defined 8319 function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) { 8320 // if more than one week row, or if there are a lot of columns with not much space, 8321 // put just the day numbers will be in each cell 8322 if (!datesRepDistinctDays || dayCnt > 10) { 8323 return createFormatter({ weekday: 'short' }); // "Sat" 8324 } 8325 if (dayCnt > 1) { 8326 return createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }); // "Sat 11/12" 8327 } 8328 return createFormatter({ weekday: 'long' }); // "Saturday" 8329 } 8330 8331 var CLASS_NAME = 'fc-col-header-cell'; // do the cushion too? no 8332 function renderInner$1(hookProps) { 8333 return hookProps.text; 8334 } 8335 8336 var TableDateCell = /** @class */ (function (_super) { 8337 __extends(TableDateCell, _super); 8338 function TableDateCell() { 8339 return _super !== null && _super.apply(this, arguments) || this; 8340 } 8341 TableDateCell.prototype.render = function () { 8342 var _a = this.context, dateEnv = _a.dateEnv, options = _a.options, theme = _a.theme, viewApi = _a.viewApi; 8343 var props = this.props; 8344 var date = props.date, dateProfile = props.dateProfile;
8345 var dayMeta = getDateMeta(date, props.todayRange, null, dateProfile); 8346 var classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme)); 8347 var text = dateEnv.format(date, props.dayHeaderFormat); 8348 // if colCnt is 1, we are already in a day-view and don't need a navlink 8349 var navLinkAttrs = (!dayMeta.isDisabled && props.colCnt > 1) 8350 ? buildNavLinkAttrs(this.context, date) 8351 : {}; 8352 var hookProps = __assign(__assign(__assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraHookProps), { text: text }), dayMeta); 8353 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), 8354 createElement("div", { className: "fc-scrollgrid-sync-inner" }, !dayMeta.isDisabled && (createElement("a", __assign({ ref: innerElRef, className: [ 8355 'fc-col-header-cell-cushion', 8356 props.isSticky ? 'fc-sticky' : '', 8357 ].join(' ') }, navLinkAttrs), innerContent))))); })); 8358 }; 8359 return TableDateCell; 8360 }(BaseComponent)); 8361 8362 var WEEKDAY_FORMAT = createFormatter({ weekday: 'long' }); 8363 var TableDowCell = /** @class */ (function (_super) { 8364 __extends(TableDowCell, _super); 8365 function TableDowCell() { 8366 return _super !== null && _super.apply(this, arguments) || this; 8367 } 8368 TableDowCell.prototype.render = function () { 8369 var props = this.props; 8370 var _a = this.context, dateEnv = _a.dateEnv, theme = _a.theme, viewApi = _a.viewApi, options = _a.options; 8371 var date = addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT 8372 var dateMeta = { 8373 dow: props.dow, 8374 isDisabled: false, 8375 isFuture: false, 8376 isPast: false, 8377 isToday: false, 8378 isOther: false, 8379 }; 8380 var classNames = [CLASS_NAME].concat(getDayClassNames(dateMeta, theme), props.extraClassNames || []); 8381 var text = dateEnv.format(date, props.dayHeaderFormat); 8382 var hookProps = __assign(__assign(__assign(__assign({ // TODO: make this public? 8383 date: date }, dateMeta), { view: viewApi }), props.extraHookProps), { text: text }); 8384 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(' '), colSpan: props.colSpan }, props.extraDataAttrs), 8385 createElement("div", { className: "fc-scrollgrid-sync-inner" }, 8386 createElement("a", { "aria-label": dateEnv.format(date, WEEKDAY_FORMAT), className: [ 8387 'fc-col-header-cell-cushion', 8388 props.isSticky ? 'fc-sticky' : '', 8389 ].join(' '), ref: innerElRef }, innerContent)))); })); 8390 }; 8391 return TableDowCell; 8392 }(BaseComponent)); 8393 8394 var NowTimer = /** @class */ (function (_super) { 8395 __extends(NowTimer, _super); 8396 function NowTimer(props, context) { 8397 var _this = _super.call(this, props, context) || this; 8398 _this.initialNowDate = getNow(context.options.now, context.dateEnv); 8399 _this.initialNowQueriedMs = new Date().valueOf(); 8400 _this.state = _this.computeTiming().currentState; 8401 return _this; 8402 } 8403 NowTimer.prototype.render = function () { 8404 var _a = this, props = _a.props, state = _a.state; 8405 return props.children(state.nowDate, state.todayRange); 8406 }; 8407 NowTimer.prototype.componentDidMount = function () { 8408 this.setTimeout(); 8409 }; 8410 NowTimer.prototype.componentDidUpdate = function (prevProps) { 8411 if (prevProps.unit !== this.props.unit) { 8412 this.clearTimeout(); 8413 this.setTimeout(); 8414 } 8415 }; 8416 NowTimer.prototype.componentWillUnmount = function () { 8417 this.clearTimeout(); 8418 }; 8419 NowTimer.prototype.computeTiming = function () { 8420 var _a = this, props = _a.props, context = _a.context; 8421 var unroundedNow = addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs); 8422 var currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit); 8423 var nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit)); 8424 var waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf(); 8425 // there is a max setTimeout ms value (https://stackoverflow.com/a/3468650/96342) 8426 // ensure no longer than a day 8427 waitMs = Math.min(1000 * 60 * 60 * 24, waitMs); 8428 return { 8429 currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) }, 8430 nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) }, 8431 waitMs: waitMs, 8432 }; 8433 }; 8434 NowTimer.prototype.setTimeout = function () { 8435 var _this = this; 8436 var _a = this.computeTiming(), nextState = _a.nextState, waitMs = _a.waitMs; 8437 this.timeoutId = setTimeout(function () { 8438 _this.setState(nextState, function () { 8439 _this.setTimeout(); 8440 }); 8441 }, waitMs); 8442 }; 8443 NowTimer.prototype.clearTimeout = function () { 8444 if (this.timeoutId) { 8445 clearTimeout(this.timeoutId); 8446 } 8447 }; 8448 NowTimer.contextType = ViewContextType; 8449 return NowTimer; 8450 }(Component)); 8451 function buildDayRange(date) { 8452 var start = startOfDay(date); 8453 var end = addDays(start, 1); 8454 return { start: start, end: end }; 8455 } 8456 8457 var DayHeader = /** @class */ (function (_super) { 8458 __extends(DayHeader, _super); 8459 function DayHeader() { 8460 var _this = _super !== null && _super.apply(this, arguments) || this; 8461 _this.createDayHeaderFormatter = memoize(createDayHeaderFormatter); 8462 return _this; 8463 } 8464 DayHeader.prototype.render = function () { 8465 var context = this.context; 8466 var _a = this.props, dates = _a.dates, dateProfile = _a.dateProfile, datesRepDistinctDays = _a.datesRepDistinctDays, renderIntro = _a.renderIntro; 8467 var dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length); 8468 return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement("tr", { role: "row" }, 8469 renderIntro && renderIntro('day'), 8470 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 }))); }))); })); 8471 }; 8472 return DayHeader; 8473 }(BaseComponent)); 8474 function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) { 8475 return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt); 8476 } 8477
8478 var DaySeriesModel = /** @class */ (function () { 8479 function DaySeriesModel(range, dateProfileGenerator) { 8480 var date = range.start; 8481 var end = range.end; 8482 var indices = []; 8483 var dates = []; 8484 var dayIndex = -1; 8485 while (date < end) { // loop each day from start to end 8486 if (dateProfileGenerator.isHiddenDay(date)) { 8487 indices.push(dayIndex + 0.5); // mark that it's between indices 8488 } 8489 else { 8490 dayIndex += 1; 8491 indices.push(dayIndex); 8492 dates.push(date); 8493 } 8494 date = addDays(date, 1); 8495 } 8496 this.dates = dates; 8497 this.indices = indices; 8498 this.cnt = dates.length; 8499 } 8500 DaySeriesModel.prototype.sliceRange = function (range) { 8501 var firstIndex = this.getDateDayIndex(range.start); // inclusive first index 8502 var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index 8503 var clippedFirstIndex = Math.max(0, firstIndex); 8504 var clippedLastIndex = Math.min(this.cnt - 1, lastIndex); 8505 // deal with in-between indices 8506 clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell 8507 clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell 8508 if (clippedFirstIndex <= clippedLastIndex) { 8509 return { 8510 firstIndex: clippedFirstIndex, 8511 lastIndex: clippedLastIndex, 8512 isStart: firstIndex === clippedFirstIndex, 8513 isEnd: lastIndex === clippedLastIndex, 8514 }; 8515 } 8516 return null; 8517 }; 8518 // Given a date, returns its chronolocial cell-index from the first cell of the grid. 8519 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets. 8520 // If before the first offset, returns a negative number. 8521 // If after the last offset, returns an offset past the last cell offset. 8522 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells. 8523 DaySeriesModel.prototype.getDateDayIndex = function (date) { 8524 var indices = this.indices; 8525 var dayOffset = Math.floor(diffDays(this.dates[0], date)); 8526 if (dayOffset < 0) { 8527 return indices[0] - 1; 8528 } 8529 if (dayOffset >= indices.length) { 8530 return indices[indices.length - 1] + 1; 8531 } 8532 return indices[dayOffset]; 8533 };
8534 return DaySeriesModel; 8535 }()); 8536 8537 var DayTableModel = /** @class */ (function () { 8538 function DayTableModel(daySeries, breakOnWeeks) { 8539 var dates = daySeries.dates; 8540 var daysPerRow; 8541 var firstDay; 8542 var rowCnt; 8543 if (breakOnWeeks) { 8544 // count columns until the day-of-week repeats 8545 firstDay = dates[0].getUTCDay(); 8546 for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow += 1) { 8547 if (dates[daysPerRow].getUTCDay() === firstDay) { 8548 break; 8549 } 8550 } 8551 rowCnt = Math.ceil(dates.length / daysPerRow); 8552 } 8553 else { 8554 rowCnt = 1; 8555 daysPerRow = dates.length; 8556 } 8557 this.rowCnt = rowCnt; 8558 this.colCnt = daysPerRow; 8559 this.daySeries = daySeries; 8560 this.cells = this.buildCells(); 8561 this.headerDates = this.buildHeaderDates(); 8562 } 8563 DayTableModel.prototype.buildCells = function () { 8564 var rows = []; 8565 for (var row = 0; row < this.rowCnt; row += 1) { 8566 var cells = []; 8567 for (var col = 0; col < this.colCnt; col += 1) { 8568 cells.push(this.buildCell(row, col)); 8569 } 8570 rows.push(cells); 8571 } 8572 return rows; 8573 }; 8574 DayTableModel.prototype.buildCell = function (row, col) { 8575 var date = this.daySeries.dates[row * this.colCnt + col]; 8576 return { 8577 key: date.toISOString(), 8578 date: date, 8579 }; 8580 }; 8581 DayTableModel.prototype.buildHeaderDates = function () { 8582 var dates = []; 8583 for (var col = 0; col < this.colCnt; col += 1) { 8584 dates.push(this.cells[0][col].date); 8585 } 8586 return dates; 8587 }; 8588 DayTableModel.prototype.sliceRange = function (range) { 8589 var colCnt = this.colCnt; 8590 var seriesSeg = this.daySeries.sliceRange(range); 8591 var segs = []; 8592 if (seriesSeg) { 8593 var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex; 8594 var index = firstIndex; 8595 while (index <= lastIndex) { 8596 var row = Math.floor(index / colCnt); 8597 var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1); 8598 segs.push({ 8599 row: row, 8600 firstCol: index % colCnt, 8601 lastCol: (nextIndex - 1) % colCnt, 8602 isStart: seriesSeg.isStart && index === firstIndex, 8603 isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex, 8604 }); 8605 index = nextIndex; 8606 } 8607 } 8608 return segs; 8609 }; 8610 return DayTableModel; 8611 }()); 8612 8613 var Slicer = /** @class */ (function () { 8614 function Slicer() { 8615 this.sliceBusinessHours = memoize(this._sliceBusinessHours); 8616 this.sliceDateSelection = memoize(this._sliceDateSpan); 8617 this.sliceEventStore = memoize(this._sliceEventStore); 8618 this.sliceEventDrag = memoize(this._sliceInteraction); 8619 this.sliceEventResize = memoize(this._sliceInteraction); 8620 this.forceDayIfListItem = false; // hack 8621 } 8622 Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, context) { 8623 var extraArgs = []; 8624 for (var _i = 4; _i < arguments.length; _i++) { 8625 extraArgs[_i - 4] = arguments[_i]; 8626 } 8627 var eventUiBases = props.eventUiBases; 8628 var eventSegs = this.sliceEventStore.apply(this, __spreadArray([props.eventStore, eventUiBases, dateProfile, nextDayThreshold], extraArgs)); 8629 return { 8630 dateSelectionSegs: this.sliceDateSelection.apply(this, __spreadArray([props.dateSelection, eventUiBases, context], extraArgs)), 8631 businessHourSegs: this.sliceBusinessHours.apply(this, __spreadArray([props.businessHours, dateProfile, nextDayThreshold, context], extraArgs)), 8632 fgEventSegs: eventSegs.fg, 8633 bgEventSegs: eventSegs.bg, 8634 eventDrag: this.sliceEventDrag.apply(this, __spreadArray([props.eventDrag, eventUiBases, dateProfile, nextDayThreshold], extraArgs)), 8635 eventResize: this.sliceEventResize.apply(this, __spreadArray([props.eventResize, eventUiBases, dateProfile, nextDayThreshold], extraArgs)), 8636 eventSelection: props.eventSelection, 8637 }; // TODO: give interactionSegs? 8638 }; 8639 Slicer.prototype.sliceNowDate = function (// does not memoize 8640 date, context) { 8641 var extraArgs = []; 8642 for (var _i = 2; _i < arguments.length; _i++) { 8643 extraArgs[_i - 2] = arguments[_i]; 8644 } 8645 return this._sliceDateSpan.apply(this, __spreadArray([{ range: { start: date, end: addMs(date, 1) }, allDay: false }, 8646 {}, 8647 context], extraArgs)); 8648 }; 8649 Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, context) { 8650 var extraArgs = []; 8651 for (var _i = 4; _i < arguments.length; _i++) { 8652 extraArgs[_i - 4] = arguments[_i]; 8653 } 8654 if (!businessHours) { 8655 return []; 8656 } 8657 return this._sliceEventStore.apply(this, __spreadArray([expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context), 8658 {}, 8659 dateProfile, 8660 nextDayThreshold], extraArgs)).bg; 8661 }; 8662 Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold) { 8663 var extraArgs = []; 8664 for (var _i = 4; _i < arguments.length; _i++) { 8665 extraArgs[_i - 4] = arguments[_i]; 8666 } 8667 if (eventStore) { 8668 var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 8669 return { 8670 bg: this.sliceEventRanges(rangeRes.bg, extraArgs), 8671 fg: this.sliceEventRanges(rangeRes.fg, extraArgs), 8672 }; 8673 } 8674 return { bg: [], fg: [] }; 8675 }; 8676 Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold) { 8677 var extraArgs = []; 8678 for (var _i = 4; _i < arguments.length; _i++) { 8679 extraArgs[_i - 4] = arguments[_i]; 8680 } 8681 if (!interaction) { 8682 return null; 8683 } 8684 var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 8685 return { 8686 segs: this.sliceEventRanges(rangeRes.fg, extraArgs), 8687 affectedInstances: interaction.affectedEvents.instances, 8688 isEvent: interaction.isEvent, 8689 }; 8690 }; 8691 Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, context) { 8692 var extraArgs = []; 8693 for (var _i = 3; _i < arguments.length; _i++) { 8694 extraArgs[_i - 3] = arguments[_i]; 8695 } 8696 if (!dateSpan) { 8697 return []; 8698 } 8699 var eventRange = fabricateEventRange(dateSpan, eventUiBases, context); 8700 var segs = this.sliceRange.apply(this, __spreadArray([dateSpan.range], extraArgs)); 8701 for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) { 8702 var seg = segs_1[_a]; 8703 seg.eventRange = eventRange; 8704 } 8705 return segs; 8706 }; 8707 /* 8708 "complete" seg means it has component and eventRange 8709 */ 8710 Slicer.prototype.sliceEventRanges = function (eventRanges, extraArgs) { 8711 var segs = []; 8712 for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) { 8713 var eventRange = eventRanges_1[_i]; 8714 segs.push.apply(segs, this.sliceEventRange(eventRange, extraArgs)); 8715 } 8716 return segs; 8717 }; 8718 /* 8719 "complete" seg means it has component and eventRange 8720 */ 8721 Slicer.prototype.sliceEventRange = function (eventRange, extraArgs) { 8722 var dateRange = eventRange.range; 8723 // hack to make multi-day events that are being force-displayed as list-items to take up only one day 8724 if (this.forceDayIfListItem && eventRange.ui.display === 'list-item') { 8725 dateRange = { 8726 start: dateRange.start, 8727 end: addDays(dateRange.start, 1), 8728 }; 8729 } 8730 var segs = this.sliceRange.apply(this, __spreadArray([dateRange], extraArgs)); 8731 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 8732 var seg = segs_2[_i]; 8733 seg.eventRange = eventRange; 8734 seg.isStart = eventRange.isStart && seg.isStart; 8735 seg.isEnd = eventRange.isEnd && seg.isEnd; 8736 } 8737 return segs; 8738 }; 8739 return Slicer; 8740 }()); 8741 /* 8742 for incorporating slotMinTime/slotMaxTime if appropriate 8743 TODO: should be part of DateProfile! 8744 TimelineDateProfile already does this btw 8745 */ 8746 function computeActiveRange(dateProfile, isComponentAllDay) { 8747 var range = dateProfile.activeRange; 8748 if (isComponentAllDay) { 8749 return range; 8750 } 8751 return { 8752 start: addMs(range.start, dateProfile.slotMinTime.milliseconds), 8753 end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5), // 864e5 = ms in a day 8754 }; 8755 } 8756 8757 // high-level segmenting-aware tester functions 8758 // ------------------------------------------------------------------------------------------------------------------------ 8759 function isInteractionValid(interaction, dateProfile, context) { 8760 var instances = interaction.mutatedEvents.instances; 8761 for (var instanceId in instances) { 8762 if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) { 8763 return false;
8764 } 8765 } 8766 return isNewPropsValid({ eventDrag: interaction }, context); // HACK: the eventDrag props is used for ALL interactions 8767 } 8768 function isDateSelectionValid(dateSelection, dateProfile, context) { 8769 if (!rangeContainsRange(dateProfile.validRange, dateSelection.range)) { 8770 return false; 8771 } 8772 return isNewPropsValid({ dateSelection: dateSelection }, context); 8773 } 8774 function isNewPropsValid(newProps, context) { 8775 var calendarState = context.getCurrentData(); 8776 var props = __assign({ businessHours: calendarState.businessHours, dateSelection: '', eventStore: calendarState.eventStore, eventUiBases: calendarState.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps); 8777 return (context.pluginHooks.isPropsValid || isPropsValid)(props, context); 8778 } 8779 function isPropsValid(state, context, dateSpanMeta, filterConfig) { 8780 if (dateSpanMeta === void 0) { dateSpanMeta = {}; } 8781 if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) { 8782 return false; 8783 } 8784 if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) { 8785 return false; 8786 } 8787 return true; 8788 } 8789 // Moving Event Validation 8790 // ------------------------------------------------------------------------------------------------------------------------ 8791 function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) { 8792 var currentState = context.getCurrentData(); 8793 var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions 8794 var subjectEventStore = interaction.mutatedEvents; 8795 var subjectDefs = subjectEventStore.defs; 8796 var subjectInstances = subjectEventStore.instances; 8797 var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ? 8798 state.eventUiBases : 8799 { '': currentState.selectionConfig }); 8800 if (filterConfig) { 8801 subjectConfigs = mapHash(subjectConfigs, filterConfig); 8802 } 8803 // exclude the subject events. TODO: exclude defs too? 8804 var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); 8805 var otherDefs = otherEventStore.defs; 8806 var otherInstances = otherEventStore.instances; 8807 var otherConfigs = compileEventUis(otherDefs, state.eventUiBases); 8808 for (var subjectInstanceId in subjectInstances) { 8809 var subjectInstance = subjectInstances[subjectInstanceId]; 8810 var subjectRange = subjectInstance.range; 8811 var subjectConfig = subjectConfigs[subjectInstance.defId]; 8812 var subjectDef = subjectDefs[subjectInstance.defId]; 8813 // constraint 8814 if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) { 8815 return false; 8816 } 8817 // overlap 8818 var eventOverlap = context.options.eventOverlap; 8819 var eventOverlapFunc = typeof eventOverlap === 'function' ? eventOverlap : null; 8820 for (var otherInstanceId in otherInstances) { 8821 var otherInstance = otherInstances[otherInstanceId]; 8822 // intersect! evaluate 8823 if (rangesIntersect(subjectRange, otherInstance.range)) { 8824 var otherOverlap = otherConfigs[otherInstance.defId].overlap; 8825 // consider the other event's overlap. only do this if the subject event is a "real" event 8826 if (otherOverlap === false && interaction.isEvent) { 8827 return false; 8828 } 8829 if (subjectConfig.overlap === false) { 8830 return false; 8831 } 8832 if (eventOverlapFunc && !eventOverlapFunc(new EventApi(context, otherDefs[otherInstance.defId], otherInstance), // still event 8833 new EventApi(context, subjectDef, subjectInstance))) { 8834 return false;
8835 } 8836 } 8837 } 8838 // allow (a function) 8839 var calendarEventStore = currentState.eventStore; // need global-to-calendar, not local to component (splittable)state 8840 for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) { 8841 var subjectAllow = _a[_i]; 8842 var subjectDateSpan = __assign(__assign({}, dateSpanMeta), { range: subjectInstance.range, allDay: subjectDef.allDay }); 8843 var origDef = calendarEventStore.defs[subjectDef.defId]; 8844 var origInstance = calendarEventStore.instances[subjectInstanceId]; 8845 var eventApi = void 0; 8846 if (origDef) { // was previously in the calendar 8847 eventApi = new EventApi(context, origDef, origInstance); 8848 } 8849 else { // was an external event 8850 eventApi = new EventApi(context, subjectDef); // no instance, because had no dates 8851 } 8852 if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) { 8853 return false; 8854 } 8855 } 8856 } 8857 return true; 8858 } 8859 // Date Selection Validation 8860 // ------------------------------------------------------------------------------------------------------------------------ 8861 function isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) { 8862 var relevantEventStore = state.eventStore; 8863 var relevantDefs = relevantEventStore.defs; 8864 var relevantInstances = relevantEventStore.instances; 8865 var selection = state.dateSelection; 8866 var selectionRange = selection.range; 8867 var selectionConfig = context.getCurrentData().selectionConfig; 8868 if (filterConfig) { 8869 selectionConfig = filterConfig(selectionConfig); 8870 } 8871 // constraint 8872 if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) { 8873 return false; 8874 } 8875 // overlap 8876 var selectOverlap = context.options.selectOverlap; 8877 var selectOverlapFunc = typeof selectOverlap === 'function' ? selectOverlap : null; 8878 for (var relevantInstanceId in relevantInstances) { 8879 var relevantInstance = relevantInstances[relevantInstanceId]; 8880 // intersect! evaluate 8881 if (rangesIntersect(selectionRange, relevantInstance.range)) { 8882 if (selectionConfig.overlap === false) { 8883 return false; 8884 } 8885 if (selectOverlapFunc && !selectOverlapFunc(new EventApi(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) { 8886 return false; 8887 } 8888 } 8889 } 8890 // allow (a function) 8891 for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) { 8892 var selectionAllow = _a[_i]; 8893 var fullDateSpan = __assign(__assign({}, dateSpanMeta), selection); 8894 if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) { 8895 return false; 8896 } 8897 } 8898 return true; 8899 } 8900 // Constraint Utils 8901 // ------------------------------------------------------------------------------------------------------------------------ 8902 function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) { 8903 for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) { 8904 var constraint = constraints_1[_i]; 8905 if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) { 8906 return false; 8907 } 8908 } 8909 return true; 8910 } 8911 function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours 8912 otherEventStore, // for if constraint is an even group ID 8913 businessHoursUnexpanded, // for if constraint is 'businessHours' 8914 context) { 8915 if (constraint === 'businessHours') { 8916 return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context)); 8917 } 8918 if (typeof constraint === 'string') { // an group ID 8919 return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) { return eventDef.groupId === constraint; })); 8920 } 8921 if (typeof constraint === 'object' && constraint) { // non-null object 8922 return eventStoreToRanges(expandRecurring(constraint, subjectRange, context)); 8923 } 8924 return []; // if it's false 8925 } 8926 // TODO: move to event-store file? 8927 function eventStoreToRanges(eventStore) { 8928 var instances = eventStore.instances; 8929 var ranges = []; 8930 for (var instanceId in instances) { 8931 ranges.push(instances[instanceId].range); 8932 } 8933 return ranges; 8934 } 8935 // TODO: move to geom file? 8936 function anyRangesContainRange(outerRanges, innerRange) { 8937 for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) { 8938 var outerRange = outerRanges_1[_i]; 8939 if (rangeContainsRange(outerRange, innerRange)) { 8940 return true; 8941 } 8942 } 8943 return false;
8944 } 8945 8946 var VISIBLE_HIDDEN_RE = /^(visible|hidden)$/; 8947 var Scroller = /** @class */ (function (_super) { 8948 __extends(Scroller, _super); 8949 function Scroller() { 8950 var _this = _super !== null && _super.apply(this, arguments) || this; 8951 _this.handleEl = function (el) { 8952 _this.el = el; 8953 setRef(_this.props.elRef, el); 8954 }; 8955 return _this; 8956 } 8957 Scroller.prototype.render = function () { 8958 var props = this.props; 8959 var liquid = props.liquid, liquidIsAbsolute = props.liquidIsAbsolute; 8960 var isAbsolute = liquid && liquidIsAbsolute; 8961 var className = ['fc-scroller']; 8962 if (liquid) { 8963 if (liquidIsAbsolute) { 8964 className.push('fc-scroller-liquid-absolute'); 8965 } 8966 else { 8967 className.push('fc-scroller-liquid'); 8968 } 8969 } 8970 return (createElement("div", { ref: this.handleEl, className: className.join(' '), style: { 8971 overflowX: props.overflowX, 8972 overflowY: props.overflowY, 8973 left: (isAbsolute && -(props.overcomeLeft || 0)) || '', 8974 right: (isAbsolute && -(props.overcomeRight || 0)) || '', 8975 bottom: (isAbsolute && -(props.overcomeBottom || 0)) || '', 8976 marginLeft: (!isAbsolute && -(props.overcomeLeft || 0)) || '', 8977 marginRight: (!isAbsolute && -(props.overcomeRight || 0)) || '', 8978 marginBottom: (!isAbsolute && -(props.overcomeBottom || 0)) || '', 8979 maxHeight: props.maxHeight || '', 8980 } }, props.children)); 8981 }; 8982 Scroller.prototype.needsXScrolling = function () { 8983 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 8984 return false; 8985 } 8986 // testing scrollWidth>clientWidth is unreliable cross-browser when pixel heights aren't integers. 8987 // much more reliable to see if children are taller than the scroller, even tho doesn't account for 8988 // inner-child margins and absolute positioning 8989 var el = this.el; 8990 var realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth(); 8991 var children = el.children; 8992 for (var i = 0; i < children.length; i += 1) { 8993 var childEl = children[i]; 8994 if (childEl.getBoundingClientRect().width > realClientWidth) { 8995 return true; 8996 } 8997 } 8998 return false; 8999 }; 9000 Scroller.prototype.needsYScrolling = function () { 9001 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 9002 return false; 9003 } 9004 // testing scrollHeight>clientHeight is unreliable cross-browser when pixel heights aren't integers. 9005 // much more reliable to see if children are taller than the scroller, even tho doesn't account for 9006 // inner-child margins and absolute positioning 9007 var el = this.el; 9008 var realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth(); 9009 var children = el.children; 9010 for (var i = 0; i < children.length; i += 1) { 9011 var childEl = children[i]; 9012 if (childEl.getBoundingClientRect().height > realClientHeight) { 9013 return true; 9014 } 9015 } 9016 return false; 9017 }; 9018 Scroller.prototype.getXScrollbarWidth = function () { 9019 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 9020 return 0; 9021 } 9022 return this.el.offsetHeight - this.el.clientHeight; // only works because we guarantee no borders. TODO: add to CSS with important? 9023 }; 9024 Scroller.prototype.getYScrollbarWidth = function () { 9025 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 9026 return 0; 9027 } 9028 return this.el.offsetWidth - this.el.clientWidth;
9028 // only works because we guarantee no borders. TODO: add to CSS with important? 9029 }; 9030 return Scroller; 9031 }(BaseComponent)); 9032 9033 /* 9034 TODO: somehow infer OtherArgs from masterCallback? 9035 TODO: infer RefType from masterCallback if provided 9036 */ 9037 var RefMap = /** @class */ (function () { 9038 function RefMap(masterCallback) { 9039 var _this = this; 9040 this.masterCallback = masterCallback; 9041 this.currentMap = {}; 9042 this.depths = {}; 9043 this.callbackMap = {}; 9044 this.handleValue = function (val, key) { 9045 var _a = _this, depths = _a.depths, currentMap = _a.currentMap; 9046 var removed = false; 9047 var added = false; 9048 if (val !== null) { 9049 // for bug... ACTUALLY: can probably do away with this now that callers don't share numeric indices anymore 9050 removed = (key in currentMap); 9051 currentMap[key] = val; 9052 depths[key] = (depths[key] || 0) + 1; 9053 added = true; 9054 } 9055 else { 9056 depths[key] -= 1; 9057 if (!depths[key]) { 9058 delete currentMap[key]; 9059 delete _this.callbackMap[key]; 9060 removed = true; 9061 } 9062 } 9063 if (_this.masterCallback) { 9064 if (removed) { 9065 _this.masterCallback(null, String(key)); 9066 } 9067 if (added) { 9068 _this.masterCallback(val, String(key)); 9069 } 9070 } 9071 }; 9072 } 9073 RefMap.prototype.createRef = function (key) { 9074 var _this = this; 9075 var refCallback = this.callbackMap[key]; 9076 if (!refCallback) { 9077 refCallback = this.callbackMap[key] = function (val) { 9078 _this.handleValue(val, String(key)); 9079 }; 9080 } 9081 return refCallback; 9082 }; 9083 // TODO: check callers that don't care about order. should use getAll instead 9084 // NOTE: this method has become less valuable now that we are encouraged to map order by some other index 9085 // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and "collect" 9086 RefMap.prototype.collect = function (startIndex, endIndex, step) { 9087 return collectFromHash(this.currentMap, startIndex, endIndex, step); 9088 }; 9089 RefMap.prototype.getAll = function () { 9090 return hashValuesToArray(this.currentMap); 9091 }; 9092 return RefMap; 9093 }()); 9094 9095 function computeShrinkWidth(chunkEls) { 9096 var shrinkCells = findElements(chunkEls, '.fc-scrollgrid-shrink'); 9097 var largestWidth = 0; 9098 for (var _i = 0, shrinkCells_1 = shrinkCells; _i < shrinkCells_1.length; _i++) { 9099 var shrinkCell = shrinkCells_1[_i]; 9100 largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell)); 9101 } 9102 return Math.ceil(largestWidth); // <table> elements work best with integers. round up to ensure contents fits 9103 } 9104 function getSectionHasLiquidHeight(props, sectionConfig) { 9105 return props.liquid && sectionConfig.liquid; // does the section do liquid-height? (need to have whole scrollgrid liquid-height as well) 9106 } 9107 function getAllowYScrolling(props, sectionConfig) { 9108 return sectionConfig.maxHeight != null || // if its possible for the height to max out, we might need scrollbars 9109 getSectionHasLiquidHeight(props, sectionConfig); // if the section is liquid height, it might condense enough to require scrollbars 9110 } 9111 // TODO: ONLY use `arg`. force out internal function to use same API 9112 function renderChunkContent(sectionConfig, chunkConfig, arg, isHeader) { 9113 var expandRows = arg.expandRows; 9114 var content = typeof chunkConfig.content === 'function' ? 9115 chunkConfig.content(arg) : 9116 createElement('table', { 9117 role: 'presentation', 9118 className: [ 9119 chunkConfig.tableClassName, 9120 sectionConfig.syncRowHeights ? 'fc-scrollgrid-sync-table' : '', 9121 ].join(' '), 9122 style: { 9123 minWidth: arg.tableMinWidth, 9124 width: arg.clientWidth, 9125 height: expandRows ? arg.clientHeight : '', // css `height` on a <table> serves as a min-height 9126 }, 9127 }, arg.tableColGroupNode, createElement(isHeader ? 'thead' : 'tbody', { 9128 role: 'presentation', 9129 }, typeof chunkConfig.rowContent === 'function' 9130 ? chunkConfig.rowContent(arg) 9131 : chunkConfig.rowContent)); 9132 return content; 9133 } 9134 function isColPropsEqual(cols0, cols1) { 9135 return isArraysEqual(cols0, cols1, isPropsEqual); 9136 } 9137 function renderMicroColGroup(cols, shrinkWidth) { 9138 var colNodes = []; 9139 /* 9140 for ColProps with spans, it would have been great to make a single <col span=""> 9141 HOWEVER, Chrome was getting messing up distributing the width to <td>/<th> elements with colspans. 9142 SOLUTION: making individual <col> elements makes Chrome behave. 9143 */ 9144 for (var _i = 0, cols_1 = cols; _i < cols_1.length; _i++) { 9145 var colProps = cols_1[_i]; 9146 var span = colProps.span || 1; 9147 for (var i = 0; i < span; i += 1) {
9148 colNodes.push(createElement("col", { style: { 9149 width: colProps.width === 'shrink' ? sanitizeShrinkWidth(shrinkWidth) : (colProps.width || ''), 9150 minWidth: colProps.minWidth || '', 9151 } })); 9152 } 9153 } 9154 return createElement.apply(void 0, __spreadArray(['colgroup', {}], colNodes)); 9155 } 9156 function sanitizeShrinkWidth(shrinkWidth) { 9157 /* why 4? if we do 0, it will kill any border, which are needed for computeSmallestCellWidth 9158 4 accounts for 2 2-pixel borders. TODO: better solution? */ 9159 return shrinkWidth == null ? 4 : shrinkWidth; 9160 } 9161 function hasShrinkWidth(cols) { 9162 for (var _i = 0, cols_2 = cols; _i < cols_2.length; _i++) { 9163 var col = cols_2[_i]; 9164 if (col.width === 'shrink') { 9165 return true; 9166 } 9167 } 9168 return false; 9169 } 9170 function getScrollGridClassNames(liquid, context) { 9171 var classNames = [ 9172 'fc-scrollgrid', 9173 context.theme.getClass('table'), 9174 ]; 9175 if (liquid) { 9176 classNames.push('fc-scrollgrid-liquid'); 9177 } 9178 return classNames; 9179 } 9180 function getSectionClassNames(sectionConfig, wholeTableVGrow) { 9181 var classNames = [ 9182 'fc-scrollgrid-section', 9183 "fc-scrollgrid-section-" + sectionConfig.type, 9184 sectionConfig.className, // used? 9185 ]; 9186 if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) { 9187 classNames.push('fc-scrollgrid-section-liquid'); 9188 } 9189 if (sectionConfig.isSticky) { 9190 classNames.push('fc-scrollgrid-section-sticky'); 9191 } 9192 return classNames; 9193 }
9194 function renderScrollShim(arg) { 9195 return (createElement("div", { className: "fc-scrollgrid-sticky-shim", style: { 9196 width: arg.clientWidth, 9197 minWidth: arg.tableMinWidth, 9198 } })); 9199 } 9200 function getStickyHeaderDates(options) { 9201 var stickyHeaderDates = options.stickyHeaderDates; 9202 if (stickyHeaderDates == null || stickyHeaderDates === 'auto') { 9203 stickyHeaderDates = options.height === 'auto' || options.viewHeight === 'auto'; 9204 } 9205 return stickyHeaderDates; 9206 } 9207 function getStickyFooterScrollbar(options) { 9208 var stickyFooterScrollbar = options.stickyFooterScrollbar; 9209 if (stickyFooterScrollbar == null || stickyFooterScrollbar === 'auto') { 9210 stickyFooterScrollbar = options.height === 'auto' || options.viewHeight === 'auto'; 9211 } 9212 return stickyFooterScrollbar; 9213 } 9214 9215 var SimpleScrollGrid = /** @class */ (function (_super) { 9216 __extends(SimpleScrollGrid, _super); 9217 function SimpleScrollGrid() { 9218 var _this = _super !== null && _super.apply(this, arguments) || this; 9219 _this.processCols = memoize(function (a) { return a; }, isColPropsEqual); // so we get same `cols` props every time 9220 // yucky to memoize VNodes, but much more efficient for consumers 9221 _this.renderMicroColGroup = memoize(renderMicroColGroup); 9222 _this.scrollerRefs = new RefMap(); 9223 _this.scrollerElRefs = new RefMap(_this._handleScrollerEl.bind(_this)); 9224 _this.state = { 9225 shrinkWidth: null, 9226 forceYScrollbars: false, 9227 scrollerClientWidths: {}, 9228 scrollerClientHeights: {}, 9229 }; 9230 // TODO: can do a really simple print-view. dont need to join rows 9231 _this.handleSizing = function () { 9232 _this.setState(__assign({ shrinkWidth: _this.computeShrinkWidth() }, _this.computeScrollerDims())); 9233 }; 9234 return _this; 9235 } 9236 SimpleScrollGrid.prototype.render = function () { 9237 var _a = this, props = _a.props, state = _a.state, context = _a.context; 9238 var sectionConfigs = props.sections || []; 9239 var cols = this.processCols(props.cols); 9240 var microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth); 9241 var classNames = getScrollGridClassNames(props.liquid, context); 9242 if (props.collapsibleWidth) { 9243 classNames.push('fc-scrollgrid-collapsible'); 9244 } 9245 // TODO: make DRY 9246 var configCnt = sectionConfigs.length; 9247 var configI = 0; 9248 var currentConfig; 9249 var headSectionNodes = []; 9250 var bodySectionNodes = []; 9251 var footSectionNodes = []; 9252 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') { 9253 headSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true)); 9254 configI += 1; 9255 } 9256 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'body') { 9257 bodySectionNodes.push(this.renderSection(currentConfig, microColGroupNode, false)); 9258 configI += 1; 9259 } 9260 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'footer') { 9261 footSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true)); 9262 configI += 1; 9263 } 9264 // firefox bug: when setting height on table and there is a thead or tfoot, 9265 // the necessary height:100% on the liquid-height body section forces the *whole* table to be taller. (bug #5524) 9266 // use getCanVGrowWithinCell as a way to detect table-stupid firefox. 9267 // if so, use a simpler dom structure, jam everything into a lone tbody. 9268 var isBuggy = !getCanVGrowWithinCell(); 9269 var roleAttrs = { role: 'rowgroup' }; 9270 return createElement('table', { 9271 role: 'grid', 9272 className: classNames.join(' '), 9273 style: { height: props.height }, 9274 }, Boolean(!isBuggy && headSectionNodes.length) && createElement.apply(void 0, __spreadArray(['thead', roleAttrs], headSectionNodes
9274)), 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))); 9275 }; 9276 SimpleScrollGrid.prototype.renderSection = function (sectionConfig, microColGroupNode, isHeader) { 9277 if ('outerContent' in sectionConfig) { 9278 return (createElement(Fragment, { key: sectionConfig.key }, sectionConfig.outerContent)); 9279 } 9280 return (createElement("tr", { key: sectionConfig.key, role: "presentation", className: getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, this.renderChunkTd(sectionConfig, microColGroupNode, sectionConfig.chunk, isHeader))); 9281 }; 9282 SimpleScrollGrid.prototype.renderChunkTd = function (sectionConfig, microColGroupNode, chunkConfig, isHeader) { 9283 if ('outerContent' in chunkConfig) { 9284 return chunkConfig.outerContent; 9285 } 9286 var props = this.props; 9287 var _a = this.state, forceYScrollbars = _a.forceYScrollbars, scrollerClientWidths = _a.scrollerClientWidths, scrollerClientHeights = _a.scrollerClientHeights; 9288 var needsYScrolling = getAllowYScrolling(props, sectionConfig); // TODO: do lazily. do in section config? 9289 var isLiquid = getSectionHasLiquidHeight(props, sectionConfig); 9290 // for `!props.liquid` - is WHOLE scrollgrid natural height? 9291 // TODO: do same thing in advanced scrollgrid? prolly not b/c always has horizontal scrollbars 9292 var overflowY = !props.liquid ? 'visible' : 9293 forceYScrollbars ? 'scroll' : 9294 !needsYScrolling ? 'hidden' : 9295 'auto'; 9296 var sectionKey = sectionConfig.key; 9297 var content = renderChunkContent(sectionConfig, chunkConfig, { 9298 tableColGroupNode: microColGroupNode, 9299 tableMinWidth: '', 9300 clientWidth: (!props.collapsibleWidth && scrollerClientWidths[sectionKey] !== undefined) ? scrollerClientWidths[sectionKey] : null, 9301 clientHeight: scrollerClientHeights[sectionKey] !== undefined ? scrollerClientHeights[sectionKey] : null, 9302 expandRows: sectionConfig.expandRows, 9303 syncRowHeights: false, 9304 rowSyncHeights: [], 9305 reportRowHeightChange: function () { }, 9306 }, isHeader); 9307 return createElement(isHeader ? 'th' : 'td', { 9308 ref: chunkConfig.elRef, 9309 role: 'presentation', 9310 }, createElement("div", { className: "fc-scroller-harness" + (isLiquid ? ' fc-scroller-harness-liquid' : '') }, 9311 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 9312 : true }, content))); 9313 }; 9314 SimpleScrollGrid.prototype._handleScrollerEl = function (scrollerEl, key) { 9315 var section = getSectionByKey(this.props.sections, key); 9316 if (section) { 9317 setRef(section.chunk.scrollerElRef, scrollerEl); 9318 } 9319 }; 9320 SimpleScrollGrid.prototype.componentDidMount = function () { 9321 this.handleSizing(); 9322 this.context.addResizeHandler(this.handleSizing); 9323 }; 9324 SimpleScrollGrid.prototype.componentDidUpdate = function () { 9325 // TODO: need better solution when state contains non-sizing things 9326 this.handleSizing(); 9327 }; 9328 SimpleScrollGrid.prototype.componentWillUnmount = function () { 9329 this.context.removeResizeHandler(this.handleSizing); 9330 }; 9331 SimpleScrollGrid.prototype.computeShrinkWidth = function () { 9332 return hasShrinkWidth(this.props.cols) 9333 ? computeShrinkWidth(this.scrollerElRefs.getAll()) 9334 : 0; 9335 }; 9336 SimpleScrollGrid.prototype.computeScrollerDims = function () { 9337 var scrollbarWidth = getScrollbarWidths(); 9338 var _a = this, scrollerRefs = _a.scrollerRefs, scrollerElRefs = _a.scrollerElRefs; 9339 var forceYScrollbars = false;
9340 var scrollerClientWidths = {}; 9341 var scrollerClientHeights = {}; 9342 for (var sectionKey in scrollerRefs.currentMap) { 9343 var scroller = scrollerRefs.currentMap[sectionKey]; 9344 if (scroller && scroller.needsYScrolling()) { 9345 forceYScrollbars = true; 9346 break; 9347 } 9348 } 9349 for (var _i = 0, _b = this.props.sections; _i < _b.length; _i++) { 9350 var section = _b[_i]; 9351 var sectionKey = section.key; 9352 var scrollerEl = scrollerElRefs.currentMap[sectionKey]; 9353 if (scrollerEl) { 9354 var harnessEl = scrollerEl.parentNode; // TODO: weird way to get this. need harness b/c doesn't include table borders 9355 scrollerClientWidths[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars 9356 ? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future 9357 : 0)); 9358 scrollerClientHeights[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().height); 9359 } 9360 } 9361 return { forceYScrollbars: forceYScrollbars, scrollerClientWidths: scrollerClientWidths, scrollerClientHeights: scrollerClientHeights }; 9362 }; 9363 return SimpleScrollGrid; 9364 }(BaseComponent)); 9365 SimpleScrollGrid.addStateEquality({ 9366 scrollerClientWidths: isPropsEqual, 9367 scrollerClientHeights: isPropsEqual, 9368 }); 9369 function getSectionByKey(sections, key) { 9370 for (var _i = 0, sections_1 = sections; _i < sections_1.length; _i++) { 9371 var section = sections_1[_i]; 9372 if (section.key === key) { 9373 return section; 9374 } 9375 } 9376 return null; 9377 } 9378 9379 var EventRoot = /** @class */ (function (_super) { 9380 __extends(EventRoot, _super); 9381 function EventRoot() { 9382 var _this = _super !== null && _super.apply(this, arguments) || this; 9383 _this.elRef = createRef(); 9384 return _this; 9385 } 9386 EventRoot.prototype.render = function () { 9387 var _a = this, props = _a.props, context = _a.context; 9388 var options = context.options; 9389 var seg = props.seg; 9390 var eventRange = seg.eventRange; 9391 var ui = eventRange.ui; 9392 var hookProps = { 9393 event: new EventApi(context, eventRange.def, eventRange.instance), 9394 view: context.viewApi, 9395 timeText: props.timeText, 9396 textColor: ui.textColor, 9397 backgroundColor: ui.backgroundColor, 9398 borderColor: ui.borderColor, 9399 isDraggable: !props.disableDragging && computeSegDraggable(seg, context), 9400 isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context), 9401 isEndResizable: !props.disableResizing && computeSegEndResizable(seg), 9402 isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting), 9403 isStart: Boolean(seg.isStart), 9404 isEnd: Boolean(seg.isEnd), 9405 isPast: Boolean(props.isPast), 9406 isFuture: Boolean(props.isFuture), 9407 isToday: Boolean(props.isToday), 9408 isSelected: Boolean(props.isSelected), 9409 isDragging: Boolean(props.isDragging), 9410 isResizing: Boolean(props.isResizing), 9411 }; 9412 var standardClassNames = getEventClassNames(hookProps).concat(ui.classNames); 9413 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.concat(customClassNames), innerElRef, innerContent, hookProps); })); 9414 }; 9415 EventRoot.prototype.componentDidMount = function () { 9416 setElSeg(this.elRef.current, this.props.seg); 9417 }; 9418 /* 9419 need to re-assign seg to the element if seg changes, even if the element is the same 9420 */ 9421 EventRoot.prototype.componentDidUpdate = function (prevProps) { 9422 var seg = this.props.seg; 9423 if (seg !== prevProps.seg) { 9424 setElSeg(this.elRef.current, seg); 9425 } 9426 }; 9427 return EventRoot; 9428 }(BaseComponent)); 9429 9430 // should not be a purecomponent 9431 var StandardEvent = /** @class */ (function (_super) { 9432 __extends(StandardEvent, _super); 9433 function StandardEvent() { 9434 return _super !== null && _super.apply(this, arguments) || this; 9435 } 9436 StandardEvent.prototype.render = function () { 9437 var _a = this, props = _a.props, context = _a.context; 9438 var seg = props.seg; 9439 var timeFormat = context.options.eventTimeFormat || props.defaultTimeFormat; 9440 var timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd); 9441 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.c
9441oncat(classNames).join(' '), style: { 9442 borderColor: hookProps.borderColor, 9443 backgroundColor: hookProps.backgroundColor, 9444 }, ref: rootElRef }, getSegAnchorAttrs(seg, context)), 9445 createElement("div", { className: "fc-event-main", ref: innerElRef, style: { color: hookProps.textColor } }, innerContent), 9446 hookProps.isStartResizable && 9447 createElement("div", { className: "fc-event-resizer fc-event-resizer-start" }), 9448 hookProps.isEndResizable && 9449 createElement("div", { className: "fc-event-resizer fc-event-resizer-end" }))); })); 9450 }; 9451 return StandardEvent; 9452 }(BaseComponent)); 9453 function renderInnerContent$4(innerProps) { 9454 return (createElement("div", { className: "fc-event-main-frame" }, 9455 innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)), 9456 createElement("div", { className: "fc-event-title-container" }, 9457 createElement("div", { className: "fc-event-title fc-sticky" }, innerProps.event.title || createElement(Fragment, null, "\u00A0"))))); 9458 } 9459 9460 var NowIndicatorRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) { 9461 var options = context.options; 9462 var hookProps = { 9463 isAxis: props.isAxis, 9464 date: context.dateEnv.toDate(props.date), 9465 view: context.viewApi, 9466 }; 9467 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.nowIndicatorClassNames, content: options.nowIndicatorContent, didMount: options.nowIndicatorDidMount, willUnmount: options.nowIndicatorWillUnmount }, props.children)); 9468 })); }; 9469 9470 var DAY_NUM_FORMAT = createFormatter({ day: 'numeric' }); 9471 var DayCellContent = /** @class */ (function (_super) { 9472 __extends(DayCellContent, _super); 9473 function DayCellContent() { 9474 return _super !== null && _super.apply(this, arguments) || this; 9475 } 9476 DayCellContent.prototype.render = function () { 9477 var _a = this, props = _a.props, context = _a.context; 9478 var options = context.options; 9479 var hookProps = refineDayCellHookProps({ 9480 date: props.date, 9481 dateProfile: props.dateProfile, 9482 todayRange: props.todayRange, 9483 showDayNumber: props.showDayNumber, 9484 extraProps: props.extraHookProps, 9485 viewApi: context.viewApi, 9486 dateEnv: context.dateEnv, 9487 }); 9488 return (createElement(ContentHook, { hookProps: hookProps, content: options.dayCellContent, defaultContent: props.defaultContent }, props.children)); 9489 }; 9490 return DayCellContent; 9491 }(BaseComponent)); 9492 function refineDayCellHookProps(raw) { 9493 var date = raw.date, dateEnv = raw.dateEnv; 9494 var dayMeta = getDateMeta(date, raw.todayRange, null, raw.dateProfile); 9495 return __assign(__assign(__assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), { dayNumberText: raw.showDayNumber ? dateEnv.format(date, DAY_NUM_FORMAT) : '' }), raw.extraProps); 9496 } 9497 9498 var DayCellRoot = /** @class */ (function (_super) { 9499 __extends(DayCellRoot, _super); 9500 function DayCellRoot() { 9501 var _this = _super !== null && _super.apply(this, arguments) || this; 9502 _this.refineHookProps = memoizeObjArg(refineDayCellHookProps); 9503 _this.normalizeClassNames = buildClassNameNormalizer(); 9504 return _this; 9505 } 9506 DayCellRoot.prototype.render = function () { 9507 var _a = this, props = _a.props, context = _a.context; 9508 var options = context.options; 9509 var hookProps = this.refineHookProps({ 9510 date: props.date, 9511 dateProfile: props.dateProfile, 9512 todayRange: props.todayRange, 9513 showDayNumber: props.showDayNumber, 9514 extraProps: props.extraHookProps, 9515 viewApi: context.viewApi, 9516 dateEnv: context.dateEnv, 9517 }); 9518 var classNames = getDayClassNames(hookProps, context.theme).concat(hookProps.isDisabled 9519 ? [] // don't use custom classNames if disabled 9520 : this.normalizeClassNames(options.dayCellClassNames, hookProps)); 9521 var dataAttrs = hookProps.isDisabled ? {} : { 9522 'data-date': formatDayString(props.date), 9523 }; 9524 return (createElement(MountHook, { hookProps: hookProps, didMount: options.dayCellDidMount, willUnmount: options.dayCellWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, classNames, dataAttrs, hookProps.isDisabled); })); 9525 }; 9526 return DayCellRoot; 9527 }(BaseComponent)); 9528 9529 function renderFill(fillType) { 9530 return (createElement("div", { className: "fc-" + fillType })); 9531 } 9532 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: { 9533 backgroundColor: hookProps.backgroundColor, 9534 } }, innerContent)); })); }; 9535 function renderInnerContent$3(props) { 9536 var title = props.event.title; 9537 return title && (createElement("div", { className: "fc-event-title" }, props.event.title)); 9538 } 9539 9540 var WeekNumberRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) { 9541 var dateEnv = context.dateEnv, options = context.options; 9542 var date = props.date; 9543 var format = options.weekNumberFormat || props.defaultFormat; 9544 var num = dateEnv.computeWeekNumber(date); // TODO: somehow use for formatting as well? 9545 var text = dateEnv.format(date, format); 9546 var hookProps = { num: num, text: text, date: date }; 9547 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.weekNumberClassNames, content: options.weekNumberContent, defaultContent: renderInner, didMount: options.weekNumberDidMount, willUnmount: options.weekNumberWillUnmount }, props.children)); 9548 })); }; 9549 function renderInner(innerProps) { 9550 return innerProps.text; 9551 } 9552 9553 var PADDING_FROM_VIEWPORT = 10; 9554 var Popover = /** @class */ (function (_super) { 9555 __extends(Popover, _super); 9556 function Popover() { 9557 var _this = _super !== null && _super.apply(this, arguments) || this; 9558 _this.state = { 9559 titleId: getUniqueDomId(), 9560 }; 9561 _this.handleRootEl = function (el) { 9562 _this.rootEl = el; 9563 if (_this.props.elRef) { 9564 setRef(_this.props.elRef, el); 9565 } 9566 }; 9567 // Triggered when the user clicks *anywhere* in the document, for the autoHide feature 9568 _this.handleDocumentMouseDown = function (ev) { 9569 // only hide the popover if the click happened outside the popover 9570 var target = getEventTargetViaRoot(ev); 9571 if (!_this.rootEl.contains(target)) { 9572 _this.handleCloseClick(); 9573 } 9574 }; 9575 _this.handleDocumentKeyDown = function (ev) { 9576 if (ev.key === 'Escape') { 9577 _this.handleCloseClick(); 9578 } 9579 }; 9580 _this.handleCloseClick = function () { 9581 var onClose = _this.props.onClose; 9582 if (onClose) { 9583 onClose(); 9584 } 9585 }; 9586 return _this; 9587 } 9588 Popover.prototype.render = function () { 9589 var _a = this.context, theme = _a.theme, options = _a.options; 9590 var _b = this, props = _b.props, state = _b.state; 9591 var classNames = [ 9592 'fc-popover', 9593 theme.getClass('popover'), 9594 ].concat(props.extraClassNames || []); 9595 return createPortal(createElement("div", __assign({ id: props.id, className: classNames.join(' '), "aria-labelledby": state.t
9595itleId }, props.extraAttrs, { ref: this.handleRootEl }), 9596 createElement("div", { className: 'fc-popover-header ' + theme.getClass('popoverHeader') }, 9597 createElement("span", { className: "fc-popover-title", id: state.titleId }, props.title), 9598 createElement("span", { className: 'fc-popover-close ' + theme.getIconClass('close'), title: options.closeHint, onClick: this.handleCloseClick })), 9599 createElement("div", { className: 'fc-popover-body ' + theme.getClass('popoverContent') }, props.children)), props.parentEl); 9600 }; 9601 Popover.prototype.componentDidMount = function () { 9602 document.addEventListener('mousedown', this.handleDocumentMouseDown); 9603 document.addEventListener('keydown', this.handleDocumentKeyDown); 9604 this.updateSize(); 9605 }; 9606 Popover.prototype.componentWillUnmount = function () { 9607 document.removeEventListener('mousedown', this.handleDocumentMouseDown); 9608 document.removeEventListener('keydown', this.handleDocumentKeyDown); 9609 }; 9610 Popover.prototype.updateSize = function () { 9611 var isRtl = this.context.isRtl; 9612 var _a = this.props, alignmentEl = _a.alignmentEl, alignGridTop = _a.alignGridTop; 9613 var rootEl = this.rootEl; 9614 var alignmentRect = computeClippedClientRect(alignmentEl); 9615 if (alignmentRect) { 9616 var popoverDims = rootEl.getBoundingClientRect(); 9617 // position relative to viewport 9618 var popoverTop = alignGridTop 9619 ? elementClosest(alignmentEl, '.fc-scrollgrid').getBoundingClientRect().top 9620 : alignmentRect.top; 9621 var popoverLeft = isRtl ? alignmentRect.right - popoverDims.width : alignmentRect.left; 9622 // constrain 9623 popoverTop = Math.max(popoverTop, PADDING_FROM_VIEWPORT); 9624 popoverLeft = Math.min(popoverLeft, document.documentElement.clientWidth - PADDING_FROM_VIEWPORT - popoverDims.width); 9625 popoverLeft = Math.max(popoverLeft, PADDING_FROM_VIEWPORT); 9626 var origin_1 = rootEl.offsetParent.getBoundingClientRect(); 9627 applyStyle(rootEl, { 9628 top: popoverTop - origin_1.top, 9629 left: popoverLeft - origin_1.left, 9630 }); 9631 } 9632 }; 9633 return Popover; 9634 }(BaseComponent)); 9635 9636 var MorePopover = /** @class */ (function (_super) { 9637 __extends(MorePopover, _super); 9638 function MorePopover() { 9639 var _this = _super !== null && _super.apply(this, arguments) || this; 9640 _this.handleRootEl = function (rootEl) { 9641 _this.rootEl = rootEl; 9642 if (rootEl) { 9643 _this.context.registerInteractiveComponent(_this, { 9644 el: rootEl, 9645 useEventCenter: false, 9646 }); 9647 } 9648 else { 9649 _this.context.unregisterInteractiveComponent(_this); 9650 } 9651 }; 9652 return _this; 9653 } 9654 MorePopover.prototype.render = function () { 9655 var _a = this.context, options = _a.options, dateEnv = _a.dateEnv; 9656 var props = this.props; 9657 var startDate = props.startDate, todayRange = props.todayRange, dateProfile = props.dateProfile; 9658 var title = dateEnv.format(startDate, options.dayPopoverFormat); 9659 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 }, 9660 createElement(DayCellContent, { date: startDate, dateProfile: dateProfile, todayRange: todayRange }, function (innerElRef, innerContent) { return (innerContent && 9661 createElement("div", { className: "fc-more-popover-misc", ref: innerElRef }, innerContent)); }), 9662 props.children)); })); 9663 }; 9664 MorePopover.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) { 9665 var _a = this, rootEl = _a.rootEl, props = _a.props; 9666 if (positionLeft >= 0 && positionLeft < elWidth && 9667 positionTop >= 0 && positionTop < elHeight) { 9668 return { 9669 dateProfile: props.dateProfile, 9670 dateSpan: __assign({ allDay: true, range: { 9671 start: props.startDate, 9672 end: props.endDate, 9673 } }, props.extraDateSpan), 9674 dayEl: rootEl, 9675 rect: { 9676 left: 0, 9677 top: 0, 9678 right: elWidth, 9679 bottom: elHeight, 9680 }, 9681 layer: 1, // important when comparing with hits from other components 9682 }; 9683 } 9684 return null; 9685 }; 9686 return MorePopover; 9687 }(DateComponent)); 9688 9689 var MoreLinkRoot = /** @class */ (function (_super) { 9690 __extends(MoreLinkRoot, _super); 9691 function MoreLinkRoot() { 9692 var _this = _super !== null && _super.apply(this, arguments) || this; 9693 _this.linkElRef = createRef(); 9694 _this.state = { 9695 isPopoverOpen: false, 9696 popoverId: getUniqueDomId(), 9697 }; 9698 _this.handleClick = function (ev) { 9699 var _a = _this, props = _a.props, context = _a.context; 9700 var moreLinkClick = context.options.moreLinkClick; 9701 var date = computeRange(props).start; 9702 function buildPublicSeg(seg) { 9703 var _a = seg.eventRange, def = _a.def, instance = _a.instance, range = _a.range; 9704 return { 9705 event: new EventApi(context, def, instance), 9706 start: context.dateEnv.toDate(range.start), 9707 end: context.dateEnv.toDate(range.end), 9708 isStart: seg.isStart, 9709 isEnd: seg.isEnd, 9710 }; 9711 } 9712 if (typeof moreLinkClick === 'function') { 9713 moreLinkClick = moreLinkClick({ 9714 date: date, 9715 allDay: Boolean(props.allDayDate), 9716 allSegs: props.allSegs.map(buildPublicSeg), 9717 hiddenSegs: props.hiddenSegs.map(buildPublicSeg), 9718 jsEvent: ev, 9719 view: context.viewApi, 9720 }); 9721 } 9722 if (!moreLinkClick || moreLinkClick === 'popover') { 9723 _this.setState({ isPopoverOpen: true }); 9724 } 9725 else if (typeof moreLinkClick === 'string') { // a view n
9725ame 9726 context.calendarApi.zoomTo(date, moreLinkClick); 9727 } 9728 }; 9729 _this.handlePopoverClose = function () { 9730 _this.setState({ isPopoverOpen: false }); 9731 }; 9732 return _this; 9733 } 9734 MoreLinkRoot.prototype.render = function () { 9735 var _this = this; 9736 var _a = this, props = _a.props, state = _a.state; 9737 return (createElement(ViewContextType.Consumer, null, function (context) { 9738 var viewApi = context.viewApi, options = context.options, calendarApi = context.calendarApi; 9739 var moreLinkText = options.moreLinkText; 9740 var moreCnt = props.moreCnt; 9741 var range = computeRange(props); 9742 var text = typeof moreLinkText === 'function' // TODO: eventually use formatWithOrdinals 9743 ? moreLinkText.call(calendarApi, moreCnt) 9744 : "+" + moreCnt + " " + moreLinkText; 9745 var title = formatWithOrdinals(options.moreLinkHint, [moreCnt], text); 9746 var hookProps = { 9747 num: moreCnt, 9748 shortText: "+" + moreCnt, 9749 text: text, 9750 view: viewApi, 9751 }; 9752 return (createElement(Fragment, null, 9753 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 : ''); })), 9754 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())))); 9755 })); 9756 }; 9757 MoreLinkRoot.prototype.componentDidMount = function () { 9758 this.updateParentEl(); 9759 }; 9760 MoreLinkRoot.prototype.componentDidUpdate = function () { 9761 this.updateParentEl(); 9762 }; 9763 MoreLinkRoot.prototype.updateParentEl = function () { 9764 if (this.linkElRef.current) { 9765 this.parentEl = elementClosest(this.linkElRef.current, '.fc-view-harness'); 9766 } 9767 }; 9768 return MoreLinkRoot; 9769 }(BaseComponent)); 9770 function renderMoreLinkInner$1(props) { 9771 return props.text; 9772 } 9773 function computeRange(props) { 9774 if (props.allDayDate) { 9775 return { 9776 start: props.allDayDate, 9777 end: addDays(props.allDayDate, 1), 9778 }; 9779 } 9780 var hiddenSegs = props.hiddenSegs; 9781 return { 9782 start: computeEarliestSegStart(hiddenSegs), 9783 end: computeLatestSegEnd(hiddenSegs), 9784 }; 9785 } 9786 function computeEarliestSegStart(segs) { 9787 return segs.reduce(pickEarliestStart).eventRange.range.start; 9788 } 9789 function pickEarliestStart(seg0, seg1) { 9790 return seg0.eventRange.range.start < seg1.eventRange.range.start ? seg0 : seg1; 9791 } 9792 function computeLatestSegEnd(segs) { 9793 return segs.reduce(pickLatestEnd).eventRange.range.end; 9794 } 9795 function pickLatestEnd(seg0, seg1) { 9796 return seg0.eventRange.range.end > seg1.eventRange.range.end ? seg0 : seg1; 9797 } 9798 9799 // exports 9800 // -------------------------------------------------------------------------------------------------- 9801 var version = '5.10.1'; // important to type it, so .d.ts has generic string 9802 9803 var Calendar = /** @class */ (function (_super) { 9804 __extends(Calendar, _super); 9805 function Calendar(el, optionOverrides) { 9806 if (optionOverrides === void 0) { optionOverrides = {}; } 9807 var _this = _super.call(this) || this; 9808 _this.isRendering = false;
9809 _this.isRendered = false; 9810 _this.currentClassNames = []; 9811 _this.customContentRenderId = 0; // will affect custom generated classNames? 9812 _this.handleAction = function (action) { 9813 // actions we know we want to render immediately 9814 switch (action.type) { 9815 case 'SET_EVENT_DRAG': 9816 case 'SET_EVENT_RESIZE': 9817 _this.renderRunner.tryDrain(); 9818 } 9819 }; 9820 _this.handleData = function (data) { 9821 _this.currentData = data; 9822 _this.renderRunner.request(data.calendarOptions.rerenderDelay); 9823 }; 9824 _this.handleRenderRequest = function () { 9825 if (_this.isRendering) { 9826 _this.isRendered = true; 9827 var currentData_1 = _this.currentData; 9828 render(createElement(CalendarRoot, { options: currentData_1.calendarOptions, theme: currentData_1.theme, emitter: currentData_1.emitter }, function (classNames, height, isHeightAuto, forPrint) { 9829 _this.setClassNames(classNames); 9830 _this.setHeight(height); 9831 return (createElement(CustomContentRenderContext.Provider, { value: _this.customContentRenderId }, 9832 createElement(CalendarContent, __assign({ isHeightAuto: isHeightAuto, forPrint: forPrint }, currentData_1)))); 9833 }), _this.el); 9834 } 9835 else if (_this.isRendered) { 9836 _this.isRendered = false; 9837 unmountComponentAtNode(_this.el); 9838 _this.setClassNames([]); 9839 _this.setHeight(''); 9840 } 9841 flushToDom(); 9842 }; 9843 _this.el = el; 9844 _this.renderRunner = new DelayedRunner(_this.handleRenderRequest); 9845 new CalendarDataManager({ 9846 optionOverrides: optionOverrides, 9847 calendarApi: _this, 9848 onAction: _this.handleAction, 9849 onData: _this.handleData, 9850 }); 9851 return _this; 9852 } 9853 Object.defineProperty(Calendar.prototype, "view", { 9854 get: function () { return this.currentData.viewApi; } // for public API 9855 , 9856 enumerable: false, 9857 configurable: true 9858 }); 9859 Calendar.prototype.render = function () { 9860 var wasRendering = this.isRendering; 9861 if (!wasRendering) { 9862 this.isRendering = true; 9863 } 9864 else { 9865 this.customContentRenderId += 1; 9866 } 9867 this.renderRunner.request(); 9868 if (wasRendering) { 9869 this.updateSize(); 9870 } 9871 }; 9872 Calendar.prototype.destroy = function () { 9873 if (this.isRendering) { 9874 this.isRendering = false; 9875 this.renderRunner.request(); 9876 } 9877 }; 9878 Calendar.prototype.updateSize = function () { 9879 _super.prototype.updateSize.call(this); 9880 flushToDom(); 9881 }; 9882 Calendar.prototype.batchRendering = function (func) { 9883 this.renderRunner.pause('batchRendering'); 9884 func(); 9885 this.renderRunner.resume('batchRendering'); 9886 }; 9887 Calendar.prototype.pauseRendering = function () { 9888 this.renderRunner.pause('pauseRendering'); 9889 }; 9890 Calendar.prototype.resumeRendering = function () { 9891 this.renderRunner.resume('pauseRendering', true); 9892 }; 9893 Calendar.prototype.resetOptions = function (optionOverrides, append) { 9894 this.currentDataManager.resetOptions(optionOverrides, append); 9895 }; 9896 Calendar.prototype.setClassNames = function (classNames) { 9897 if (!isArraysEqual(classNames, this.currentClassNames)) { 9898 var classList = this.el.classList; 9899 for (var _i = 0, _a = this.currentClassNames; _i < _a.length; _i++) { 9900 var className = _a[_i]; 9901 classList.remove(className); 9902 } 9903 for (var _b = 0, classNames_1 = classNames; _b < classNames_1.length; _b++) { 9904 var className = classNames_1[_b]; 9905 classList.add(className); 9906 } 9907 this.currentClassNames = classNames; 9908 } 9909 }; 9910 Calendar.prototype.setHeight = function (height) { 9911 applyStyleProp(this.el, 'height', height); 9912 }; 9913 return Calendar; 9914 }(CalendarApi)); 9915 9916 config.touchMouseIgnoreWait = 500; 9917 var ignoreMouseDepth = 0; 9918 var listenerCnt = 0; 9919 var isWindowTouchMoveCancelled = false;
9920 /* 9921 Uses a "pointer" abstraction, which monitors UI events for both mouse and touch. 9922 Tracks when the pointer "drags" on a certain element, meaning down+move+up. 9923 9924 Also, tracks if there was touch-scrolling. 9925 Also, can prevent touch-scrolling from happening. 9926 Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement. 9927 9928 emits: 9929 - pointerdown 9930 - pointermove 9931 - pointerup 9932 */ 9933 var PointerDragging = /** @class */ (function () { 9934 function PointerDragging(containerEl) { 9935 var _this = this; 9936 this.subjectEl = null; 9937 // options that can be directly assigned by caller 9938 this.selector = ''; // will cause subjectEl in all emitted events to be this element 9939 this.handleSelector = ''; 9940 this.shouldIgnoreMove = false; 9941 this.shouldWatchScroll = true; // for simulating pointermove on scroll 9942 // internal states 9943 this.isDragging = false; 9944 this.isTouchDragging = false; 9945 this.wasTouchScroll = false; 9946 // Mouse 9947 // ---------------------------------------------------------------------------------------------------- 9948 this.handleMouseDown = function (ev) { 9949 if (!_this.shouldIgnoreMouse() && 9950 isPrimaryMouseButton(ev) && 9951 _this.tryStart(ev)) { 9952 var pev = _this.createEventFromMouse(ev, true); 9953 _this.emitter.trigger('pointerdown', pev); 9954 _this.initScrollWatch(pev); 9955 if (!_this.shouldIgnoreMove) { 9956 document.addEventListener('mousemove', _this.handleMouseMove); 9957 } 9958 document.addEventListener('mouseup', _this.handleMouseUp); 9959 } 9960 }; 9961 this.handleMouseMove = function (ev) { 9962 var pev = _this.createEventFromMouse(ev); 9963 _this.recordCoords(pev); 9964 _this.emitter.trigger('pointermove', pev); 9965 }; 9966 this.handleMouseUp = function (ev) { 9967 document.removeEventListener('mousemove', _this.handleMouseMove); 9968 document.removeEventListener('mouseup', _this.handleMouseUp); 9969 _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev)); 9970 _this.cleanup(); // call last so that pointerup has access to props 9971 }; 9972 // Touch 9973 // ---------------------------------------------------------------------------------------------------- 9974 this.handleTouchStart = function (ev) { 9975 if (_this.tryStart(ev)) { 9976 _this.isTouchDragging = true; 9977 var pev = _this.createEventFromTouch(ev, true); 9978 _this.emitter.trigger('pointerdown', pev); 9979 _this.initScrollWatch(pev); 9980 // unlike mouse, need to attach to target, not document 9981 // https://stackoverflow.com/a/45760014 9982 var targetEl = ev.target; 9983 if (!_this.shouldIgnoreMove) { 9984 targetEl.addEventListener('touchmove', _this.handleTouchMove); 9985 } 9986 targetEl.addEventListener('touchend', _this.handleTouchEnd); 9987 targetEl.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end 9988 // attach a handler to get called when ANY scroll action happens on the page. 9989 // this was impossible to do with normal on/off because 'scroll' doesn't bubble. 9990 // http://stackoverflow.com/a/32954565/96342 9991 window.addEventListener('scroll', _this.handleTouchScroll, true); 9992 } 9993 }; 9994 this.handleTouchMove = function (ev) { 9995 var pev = _this.createEventFromTouch(ev); 9996 _this.recordCoords(pev); 9997 _this.emitter.trigger('pointermove', pev); 9998 }; 9999 this.handleTouchEnd = function (ev) { 10000 if (_this.isDragging) { // done to guard against touchend followed by touchcancel 10001 var targetEl = ev.target; 10002 targetEl.removeEventListener('touchmove', _this.handleTouchMove); 10003 targetEl.removeEventListener('touchend', _this.handleTouchEnd); 10004 targetEl.removeEventListener('touchcancel', _this.handleTouchEnd); 10005 window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true 10006 _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev)); 10007 _this.cleanup(); // call last so that pointerup has access to props 10008 _this.isTouchDragging = false;
10009 startIgnoringMouse(); 10010 } 10011 }; 10012 this.handleTouchScroll = function () { 10013 _this.wasTouchScroll = true; 10014 }; 10015 this.handleScroll = function (ev) { 10016 if (!_this.shouldIgnoreMove) { 10017 var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX; 10018 var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY; 10019 _this.emitter.trigger('pointermove', { 10020 origEvent: ev, 10021 isTouch: _this.isTouchDragging, 10022 subjectEl: _this.subjectEl, 10023 pageX: pageX, 10024 pageY: pageY, 10025 deltaX: pageX - _this.origPageX, 10026 deltaY: pageY - _this.origPageY, 10027 }); 10028 } 10029 }; 10030 this.containerEl = containerEl; 10031 this.emitter = new Emitter(); 10032 containerEl.addEventListener('mousedown', this.handleMouseDown); 10033 containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true }); 10034 listenerCreated(); 10035 } 10036 PointerDragging.prototype.destroy = function () { 10037 this.containerEl.removeEventListener('mousedown', this.handleMouseDown); 10038 this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true }); 10039 listenerDestroyed(); 10040 }; 10041 PointerDragging.prototype.tryStart = function (ev) { 10042 var subjectEl = this.querySubjectEl(ev); 10043 var downEl = ev.target; 10044 if (subjectEl && 10045 (!this.handleSelector || elementClosest(downEl, this.handleSelector))) { 10046 this.subjectEl = subjectEl; 10047 this.isDragging = true; // do this first so cancelTouchScroll will work 10048 this.wasTouchScroll = false; 10049 return true; 10050 } 10051 return false; 10052 }; 10053 PointerDragging.prototype.cleanup = function () { 10054 isWindowTouchMoveCancelled = false; 10055 this.isDragging = false; 10056 this.subjectEl = null; 10057 // keep wasTouchScroll around for later access 10058 this.destroyScrollWatch(); 10059 }; 10060 PointerDragging.prototype.querySubjectEl = function (ev) { 10061 if (this.selector) { 10062 return elementClosest(ev.target, this.selector); 10063 } 10064 return this.containerEl; 10065 }; 10066 PointerDragging.prototype.shouldIgnoreMouse = function () { 10067 return ignoreMouseDepth || this.isTouchDragging; 10068 }; 10069 // can be called by user of this class, to cancel touch-based scrolling for the current drag 10070 PointerDragging.prototype.cancelTouchScroll = function () { 10071 if (this.isDragging) { 10072 isWindowTouchMoveCancelled = true; 10073 } 10074 }; 10075 // Scrolling that simulates pointermoves 10076 // ---------------------------------------------------------------------------------------------------- 10077 PointerDragging.prototype.initScrollWatch = function (ev) { 10078 if (this.shouldWatchScroll) { 10079 this.recordCoords(ev); 10080 window.addEventListener('scroll', this.handleScroll, true); // useCapture=true 10081 } 10082 }; 10083 PointerDragging.prototype.recordCoords = function (ev) { 10084 if (this.shouldWatchScroll) { 10085 this.prevPageX = ev.pageX; 10086 this.prevPageY = ev.pageY; 10087 this.prevScrollX = window.pageXOffset; 10088 this.prevScrollY = window.pageYOffset; 10089 } 10090 }; 10091 PointerDragging.prototype.destroyScrollWatch = function () { 10092 if (this.shouldWatchScroll) { 10093 window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true 10094 } 10095 }; 10096 // Event Normalization 10097 // ---------------------------------------------------------------------------------------------------- 10098 PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) { 10099 var deltaX = 0; 10100 var deltaY = 0; 10101 // TODO: repeat code 10102 if (isFirst) { 10103 this.origPageX = ev.pageX; 10104 this.origPageY = ev.pageY; 10105 } 10106 else { 10107 deltaX = ev.pageX - this.origPageX; 10108 deltaY = ev.pageY - this.origPageY; 10109 } 10110 return { 10111 origEvent: ev, 10112 isTouch: false, 10113 subjectEl: this.subjectEl, 10114 pageX: ev.pageX, 10115 pageY: ev.pageY, 10116 deltaX: deltaX, 10117 deltaY: deltaY, 10118 }; 10119 }; 10120 PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) { 10121 var touches = ev.touches; 10122 var pageX; 10123 var pageY; 10124 var deltaX = 0; 10125 var deltaY = 0; 10126 // if touch coords available, prefer, 10127 // because FF would give bad ev.pageX ev.pageY 10128 if (touches && touches.length) { 10129 pageX = touches[0].pageX; 10130 pageY = touches[0].pageY; 10131 } 10132 else { 10133 pageX = ev.pageX; 10134 pageY = ev.pageY; 10135 } 10136 // TODO: repeat code 10137 if (isFirst) { 10138 this.origPageX = pageX; 10139 this.origPageY = pageY; 10140 } 10141 else { 10142 deltaX = pageX - this.origPageX; 10143 deltaY = pageY - this.origPageY; 10144 } 10145 return { 10146 origEvent: ev, 10147 isTouch: true, 10148 subjectEl: this.subjectEl, 10149 pageX: pageX, 10150 pageY: pageY, 10151 deltaX: deltaX, 10152 deltaY: deltaY, 10153 }; 10154 }; 10155 return PointerDragging; 10156 }());
10157 // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac) 10158 function isPrimaryMouseButton(ev) { 10159 return ev.button === 0 && !ev.ctrlKey; 10160 } 10161 // Ignoring fake mouse events generated by touch 10162 // ---------------------------------------------------------------------------------------------------- 10163 function startIgnoringMouse() { 10164 ignoreMouseDepth += 1; 10165 setTimeout(function () { 10166 ignoreMouseDepth -= 1; 10167 }, config.touchMouseIgnoreWait); 10168 } 10169 // We want to attach touchmove as early as possible for Safari 10170 // ---------------------------------------------------------------------------------------------------- 10171 function listenerCreated() { 10172 listenerCnt += 1; 10173 if (listenerCnt === 1) { 10174 window.addEventListener('touchmove', onWindowTouchMove, { passive: false }); 10175 } 10176 } 10177 function listenerDestroyed() { 10178 listenerCnt -= 1; 10179 if (!listenerCnt) { 10180 window.removeEventListener('touchmove', onWindowTouchMove, { passive: false }); 10181 } 10182 } 10183 function onWindowTouchMove(ev) { 10184 if (isWindowTouchMoveCancelled) { 10185 ev.preventDefault(); 10186 } 10187 } 10188 10189 /* 10190 An effect in which an element follows the movement of a pointer across the screen. 10191 The moving element is a clone of some other element. 10192 Must call start + handleMove + stop. 10193 */ 10194 var ElementMirror = /** @class */ (function () { 10195 function ElementMirror() { 10196 this.isVisible = false; // must be explicitly enabled 10197 this.sourceEl = null; 10198 this.mirrorEl = null; 10199 this.sourceElRect = null; // screen coords relative to viewport 10200 // options that can be set directly by caller 10201 this.parentNode = document.body; // HIGHLY SUGGESTED to set this to sidestep ShadowDOM issues 10202 this.zIndex = 9999; 10203 this.revertDuration = 0; 10204 } 10205 ElementMirror.prototype.start = function (sourceEl, pageX, pageY) { 10206 this.sourceEl = sourceEl; 10207 this.sourceElRect = this.sourceEl.getBoundingClientRect(); 10208 this.origScreenX = pageX - window.pageXOffset; 10209 this.origScreenY = pageY - window.pageYOffset; 10210 this.deltaX = 0; 10211 this.deltaY = 0; 10212 this.updateElPosition(); 10213 }; 10214 ElementMirror.prototype.handleMove = function (pageX, pageY) { 10215 this.deltaX = (pageX - window.pageXOffset) - this.origScreenX; 10216 this.deltaY = (pageY - window.pageYOffset) - this.origScreenY; 10217 this.updateElPosition(); 10218 }; 10219 // can be called before start 10220 ElementMirror.prototype.setIsVisible = function (bool) { 10221 if (bool) { 10222 if (!this.isVisible) { 10223 if (this.mirrorEl) { 10224 this.mirrorEl.style.display = ''; 10225 } 10226 this.isVisible = bool; // needs to happen before updateElPosition 10227 this.updateElPosition(); // because was not updating the position while invisible 10228 } 10229 } 10230 else if (this.isVisible) { 10231 if (this.mirrorEl) { 10232 this.mirrorEl.style.display = 'none'; 10233 } 10234 this.isVisible = bool; 10235 } 10236 }; 10237 // always async 10238 ElementMirror.prototype.stop = function (needsRevertAnimation, callback) { 10239 var _this = this; 10240 var done = function () { 10241 _this.cleanup(); 10242 callback(); 10243 }; 10244 if (needsRevertAnimation && 10245 this.mirrorEl && 10246 this.isVisible && 10247 this.revertDuration && // if 0, transition won't work 10248 (this.deltaX || this.deltaY) // if same coords, transition won't work 10249 ) { 10250 this.doRevertAnimation(done, this.revertDuration); 10251 } 10252 else { 10253 setTimeout(done, 0); 10254 } 10255 }; 10256 ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) { 10257 var mirrorEl = this.mirrorEl; 10258 var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened 10259 mirrorEl.style.transition = 10260 'top ' + revertDuration + 'ms,' + 10261 'left ' + revertDuration + 'ms'; 10262 applyStyle(mirrorEl, { 10263 left: finalSourceElRect.left, 10264 top: finalSourceElRect.top, 10265 }); 10266 whenTransitionDone(mirrorEl, function () { 10267 mirrorEl.style.transition = ''; 10268 callback(); 10269 }); 10270 }; 10271 ElementMirror.prototype.cleanup = function () { 10272 if (this.mirrorEl) { 10273 removeElement(this.mirrorEl); 10274 this.mirrorEl = null; 10275 } 10276 this.sourceEl = null; 10277 }; 10278 ElementMirror.prototype.updateElPosition = function () { 10279 if (this.sourceEl && this.isVisible) { 10280 applyStyle(this.getMirrorEl(), { 10281 left: this.sourceElRect.left + this.deltaX,
10282 top: this.sourceElRect.top + this.deltaY, 10283 }); 10284 } 10285 }; 10286 ElementMirror.prototype.getMirrorEl = function () { 10287 var sourceElRect = this.sourceElRect; 10288 var mirrorEl = this.mirrorEl; 10289 if (!mirrorEl) { 10290 mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true 10291 // we don't want long taps or any mouse interaction causing selection/menus. 10292 // would use preventSelection(), but that prevents selectstart, causing problems. 10293 mirrorEl.classList.add('fc-unselectable'); 10294 mirrorEl.classList.add('fc-event-dragging'); 10295 applyStyle(mirrorEl, { 10296 position: 'fixed', 10297 zIndex: this.zIndex, 10298 visibility: '', 10299 boxSizing: 'border-box', 10300 width: sourceElRect.right - sourceElRect.left, 10301 height: sourceElRect.bottom - sourceElRect.top, 10302 right: 'auto', 10303 bottom: 'auto', 10304 margin: 0, 10305 }); 10306 this.parentNode.appendChild(mirrorEl); 10307 } 10308 return mirrorEl; 10309 }; 10310 return ElementMirror; 10311 }()); 10312 10313 /* 10314 Is a cache for a given element's scroll information (all the info that ScrollController stores) 10315 in addition the "client rectangle" of the element.. the area within the scrollbars. 10316 10317 The cache can be in one of two modes: 10318 - doesListening:false - ignores when the container is scrolled by someone else 10319 - doesListening:true - watch for scrolling and update the cache 10320 */ 10321 var ScrollGeomCache = /** @class */ (function (_super) { 10322 __extends(ScrollGeomCache, _super); 10323 function ScrollGeomCache(scrollController, doesListening) { 10324 var _this = _super.call(this) || this; 10325 _this.handleScroll = function () { 10326 _this.scrollTop = _this.scrollController.getScrollTop(); 10327 _this.scrollLeft = _this.scrollController.getScrollLeft(); 10328 _this.handleScrollChange(); 10329 }; 10330 _this.scrollController = scrollController; 10331 _this.doesListening = doesListening; 10332 _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop(); 10333 _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft();
10334 _this.scrollWidth = scrollController.getScrollWidth(); 10335 _this.scrollHeight = scrollController.getScrollHeight(); 10336 _this.clientWidth = scrollController.getClientWidth(); 10337 _this.clientHeight = scrollController.getClientHeight(); 10338 _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values 10339 if (_this.doesListening) { 10340 _this.getEventTarget().addEventListener('scroll', _this.handleScroll); 10341 } 10342 return _this; 10343 } 10344 ScrollGeomCache.prototype.destroy = function () { 10345 if (this.doesListening) { 10346 this.getEventTarget().removeEventListener('scroll', this.handleScroll); 10347 } 10348 }; 10349 ScrollGeomCache.prototype.getScrollTop = function () { 10350 return this.scrollTop; 10351 }; 10352 ScrollGeomCache.prototype.getScrollLeft = function () { 10353 return this.scrollLeft; 10354 }; 10355 ScrollGeomCache.prototype.setScrollTop = function (top) { 10356 this.scrollController.setScrollTop(top); 10357 if (!this.doesListening) { 10358 // we are not relying on the element to normalize out-of-bounds scroll values 10359 // so we need to sanitize ourselves 10360 this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0); 10361 this.handleScrollChange(); 10362 } 10363 }; 10364 ScrollGeomCache.prototype.setScrollLeft = function (top) { 10365 this.scrollController.setScrollLeft(top); 10366 if (!this.doesListening) { 10367 // we are not relying on the element to normalize out-of-bounds scroll values 10368 // so we need to sanitize ourselves 10369 this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0); 10370 this.handleScrollChange(); 10371 } 10372 }; 10373 ScrollGeomCache.prototype.getClientWidth = function () { 10374 return this.clientWidth; 10375 }; 10376 ScrollGeomCache.prototype.getClientHeight = function () { 10377 return this.clientHeight; 10378 }; 10379 ScrollGeomCache.prototype.getScrollWidth = function () { 10380 return this.scrollWidth; 10381 }; 10382 ScrollGeomCache.prototype.getScrollHeight = function () { 10383 return this.scrollHeight; 10384 }; 10385 ScrollGeomCache.prototype.handleScrollChange = function () { 10386 }; 10387 return ScrollGeomCache; 10388 }(ScrollController)); 10389 10390 var ElementScrollGeomCache = /** @class */ (function (_super) { 10391 __extends(ElementScrollGeomCache, _super); 10392 function ElementScrollGeomCache(el, doesListening) { 10393 return _super.call(this, new ElementScrollController(el), doesListening) || this; 10394 } 10395 ElementScrollGeomCache.prototype.getEventTarget = function () { 10396 return this.scrollController.el; 10397 }; 10398 ElementScrollGeomCache.prototype.computeClientRect = function () { 10399 return computeInnerRect(this.scrollController.el); 10400 }; 10401 return ElementScrollGeomCache; 10402 }(ScrollGeomCache)); 10403 10404 var WindowScrollGeomCache = /** @class */ (function (_super) { 10405 __extends(WindowScrollGeomCache, _super); 10406 function WindowScrollGeomCache(doesListening) { 10407 return _super.call(this, new WindowScrollController(), doesListening) || this; 10408 } 10409 WindowScrollGeomCache.prototype.getEventTarget = function () { 10410 return window; 10411 }; 10412 WindowScrollGeomCache.prototype.computeClientRect = function () { 10413 return { 10414 left: this.scrollLeft, 10415 right: this.scrollLeft + this.clientWidth, 10416 top: this.scrollTop, 10417 bottom: this.scrollTop + this.clientHeight, 10418 }; 10419 }; 10420 // the window is the only scroll object that changes it's rectangle relative 10421 // to the document's topleft as it scrolls 10422 WindowScrollGeomCache.prototype.handleScrollChange = function () { 10423 this.clientRect = this.computeClientRect(); 10424 }; 10425 return WindowScrollGeomCache; 10426 }(ScrollGeomCache)); 10427 10428 // If available we are using native "performance" API instead of "Date" 10429 // Read more about it on MDN: 10430 // https://developer.mozilla.org/en-US/docs/Web/API/Performance 10431 var getTime = typeof performance === 'function' ? performance.now : Date.now; 10432 /* 10433 For a pointer interaction, automatically scrolls certain scroll containers when the pointer 10434 approaches the edge. 10435 10436 The caller must call start + handleMove + stop. 10437 */ 10438 var AutoScroller = /** @class */ (function () { 10439 function AutoScroller() { 10440 var _this = this; 10441 // options that can be set by caller 10442 this.isEnabled = true; 10443 this.scrollQuery = [window, '.fc-scroller']; 10444 this.edgeThreshold = 50; // pixels 10445 this.maxVelocity = 300; // pixels per second 10446 // internal state 10447 this.pointerScreenX = null; 10448 this.pointerScreenY = null; 10449 this.isAnimating = false;
10450 this.scrollCaches = null; 10451 // protect against the initial pointerdown being too close to an edge and starting the scroll 10452 this.everMovedUp = false; 10453 this.everMovedDown = false; 10454 this.everMovedLeft = false; 10455 this.everMovedRight = false; 10456 this.animate = function () { 10457 if (_this.isAnimating) { // wasn't cancelled between animation calls 10458 var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset); 10459 if (edge) { 10460 var now = getTime(); 10461 _this.handleSide(edge, (now - _this.msSinceRequest) / 1000); 10462 _this.requestAnimation(now); 10463 } 10464 else { 10465 _this.isAnimating = false; // will stop animation 10466 } 10467 } 10468 }; 10469 } 10470 AutoScroller.prototype.start = function (pageX, pageY, scrollStartEl) { 10471 if (this.isEnabled) { 10472 this.scrollCaches = this.buildCaches(scrollStartEl); 10473 this.pointerScreenX = null; 10474 this.pointerScreenY = null; 10475 this.everMovedUp = false; 10476 this.everMovedDown = false; 10477 this.everMovedLeft = false; 10478 this.everMovedRight = false; 10479 this.handleMove(pageX, pageY); 10480 } 10481 }; 10482 AutoScroller.prototype.handleMove = function (pageX, pageY) { 10483 if (this.isEnabled) { 10484 var pointerScreenX = pageX - window.pageXOffset; 10485 var pointerScreenY = pageY - window.pageYOffset; 10486 var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY; 10487 var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX; 10488 if (yDelta < 0) { 10489 this.everMovedUp = true; 10490 } 10491 else if (yDelta > 0) { 10492 this.everMovedDown = true; 10493 } 10494 if (xDelta < 0) { 10495 this.everMovedLeft = true; 10496 } 10497 else if (xDelta > 0) { 10498 this.everMovedRight = true; 10499 } 10500 this.pointerScreenX = pointerScreenX; 10501 this.pointerScreenY = pointerScreenY; 10502 if (!this.isAnimating) { 10503 this.isAnimating = true; 10504 this.requestAnimation(getTime()); 10505 } 10506 } 10507 }; 10508 AutoScroller.prototype.stop = function () { 10509 if (this.isEnabled) { 10510 this.isAnimating = false; // will stop animation 10511 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10512 var scrollCache = _a[_i]; 10513 scrollCache.destroy(); 10514 } 10515 this.scrollCaches = null; 10516 } 10517 }; 10518 AutoScroller.prototype.requestAnimation = function (now) { 10519 this.msSinceRequest = now; 10520 requestAnimationFrame(this.animate); 10521 }; 10522 AutoScroller.prototype.handleSide = function (edge, seconds) { 10523 var scrollCache = edge.scrollCache; 10524 var edgeThreshold = this.edgeThreshold; 10525 var invDistance = edgeThreshold - edge.distance; 10526 var velocity = // the closer to the edge, the faster we scroll 10527 ((invDistance * invDistance) / (edgeThreshold * edgeThreshold)) * // quadratic 10528 this.maxVelocity * seconds; 10529 var sign = 1; 10530 switch (edge.name) { 10531 case 'left': 10532 sign = -1; 10533 // falls through 10534 case 'right': 10535 scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign); 10536 break; 10537 case 'top': 10538 sign = -1; 10539 // falls through 10540 case 'bottom': 10541 scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign); 10542 break; 10543 } 10544 }; 10545 // left/top are relative to document topleft 10546 AutoScroller.prototype.computeBestEdge = function (left, top) { 10547 var edgeThreshold = this.edgeThreshold; 10548 var bestSide = null; 10549 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10550 var scrollCache = _a[_i]; 10551 var rect = scrollCache.clientRect; 10552 var leftDist = left - rect.left; 10553 var rightDist = rect.right - left; 10554 var topDist = top - rect.top; 10555 var bottomDist = rect.bottom - top; 10556 // completely within the rect? 10557 if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) { 10558 if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() && 10559 (!bestSide || bestSide.distance > topDist)) { 10560 bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist }; 10561 } 10562 if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() && 10563 (!bestSide || bestSide.distance > bottomDist)) { 10564 bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist }; 10565 } 10566 if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() && 10567 (!bestSide || bestSide.distance > leftDist)) { 10568 bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist }; 10569 } 10570 if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() && 10571 (!bestSide || bestSide.distance > rightDist)) { 10572 bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist }; 10573 } 10574 } 10575 } 10576 return bestSide; 10577 }; 10578 AutoScroller.prototype.buildCaches = function (scrollStartEl) { 10579 return this.queryScrollEls(scrollStartEl).map(function (el) { 10580 if (el === window) { 10581 return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls 10582 } 10583 return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls 10584 }); 10585 }; 10586 AutoScroller.prototype.queryScrollEls = function (scrollStartEl) { 10587 var els = []; 10588 for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) { 10589 var query = _a[_i]; 10590 if (typeof query === 'object') { 10591 els.push(query); 10592 } 10593 else { 10594 els.push.apply(els, Array.prototype.slice.call(getElRoot(scrollStartEl).querySelectorAll(query))); 10595 } 10596 } 10597 return els; 10598 }; 10599 return AutoScroller; 10600 }()); 10601 10602 /* 10603 Monitors dragging on an element. Has a number of high-level features: 10604 - minimum distance required before dragging 10605 - minimum wait time ("delay") before dragging 10606 - a mirror element that follows the pointer 10607 */ 10608 var FeaturefulElementDragging = /** @class */ (function (_super) { 10609 __extends(FeaturefulElementDragging, _super); 10610 function FeaturefulElementDragging(containerEl, selector) { 10611 var _this = _super.call(this, containerEl) || this; 10612 _this.containerEl = containerEl; 10613 // options that can be directly set by caller 10614 // the caller can also set the PointerDragging's options as well 10615 _this.delay = null; 10616 _this.minDistance = 0; 10617 _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag 10618 _this.mirrorNeedsRevert = false;
10619 _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup 10620 _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation 10621 _this.isDelayEnded = false; 10622 _this.isDistanceSurpassed = false; 10623 _this.delayTimeoutId = null; 10624 _this.onPointerDown = function (ev) { 10625 if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going 10626 _this.isInteracting = true; 10627 _this.isDelayEnded = false; 10628 _this.isDistanceSurpassed = false; 10629 preventSelection(document.body); 10630 preventContextMenu(document.body); 10631 // prevent links from being visited if there's an eventual drag. 10632 // also prevents selection in older browsers (maybe?). 10633 // not necessary for touch, besides, browser would complain about passiveness. 10634 if (!ev.isTouch) { 10635 ev.origEvent.preventDefault(); 10636 } 10637 _this.emitter.trigger('pointerdown', ev); 10638 if (_this.isInteracting && // not destroyed via pointerdown handler 10639 !_this.pointer.shouldIgnoreMove) { 10640 // actions related to initiating dragstart+dragmove+dragend... 10641 _this.mirror.setIsVisible(false); // reset. caller must set-visible 10642 _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down 10643 _this.startDelay(ev); 10644 if (!_this.minDistance) { 10645 _this.handleDistanceSurpassed(ev); 10646 } 10647 } 10648 } 10649 }; 10650 _this.onPointerMove = function (ev) { 10651 if (_this.isInteracting) { 10652 _this.emitter.trigger('pointermove', ev); 10653 if (!_this.isDistanceSurpassed) { 10654 var minDistance = _this.minDistance; 10655 var distanceSq = void 0; // current distance from the origin, squared 10656 var deltaX = ev.deltaX, deltaY = ev.deltaY; 10657 distanceSq = deltaX * deltaX + deltaY * deltaY; 10658 if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem 10659 _this.handleDistanceSurpassed(ev); 10660 } 10661 } 10662 if (_this.isDragging) { 10663 // a real pointer move? (not one simulated by scrolling) 10664 if (ev.origEvent.type !== 'scroll') { 10665 _this.mirror.handleMove(ev.pageX, ev.pageY); 10666 _this.autoScroller.handleMove(ev.pageX, ev.pageY); 10667 } 10668 _this.emitter.trigger('dragmove', ev); 10669 } 10670 } 10671 }; 10672 _this.onPointerUp = function (ev) { 10673 if (_this.isInteracting) { 10674 _this.isInteracting = false; 10675 allowSelection(document.body); 10676 allowContextMenu(document.body); 10677 _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert 10678 if (_this.isDragging) { 10679 _this.autoScroller.stop(); 10680 _this.tryStopDrag(ev); // which will stop the mirror 10681 } 10682 if (_this.delayTimeoutId) { 10683 clearTimeout(_this.delayTimeoutId); 10684 _this.delayTimeoutId = null; 10685 } 10686 } 10687 }; 10688 var pointer = _this.pointer = new PointerDragging(containerEl); 10689 pointer.emitter.on('pointerdown', _this.onPointerDown); 10690 pointer.emitter.on('pointermove', _this.onPointerMove); 10691 pointer.emitter.on('pointerup', _this.onPointerUp); 10692 if (selector) { 10693 pointer.selector = selector; 10694 } 10695 _this.mirror = new ElementMirror(); 10696 _this.autoScroller = new AutoScroller(); 10697 return _this; 10698 } 10699 FeaturefulElementDragging.prototype.destroy = function () { 10700 this.pointer.destroy(); 10701 // HACK: simulate a pointer-up to end the current drag
10702 // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire) 10703 this.onPointerUp({}); 10704 }; 10705 FeaturefulElementDragging.prototype.startDelay = function (ev) { 10706 var _this = this; 10707 if (typeof this.delay === 'number') { 10708 this.delayTimeoutId = setTimeout(function () { 10709 _this.delayTimeoutId = null; 10710 _this.handleDelayEnd(ev); 10711 }, this.delay); // not assignable to number! 10712 } 10713 else { 10714 this.handleDelayEnd(ev); 10715 } 10716 }; 10717 FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) { 10718 this.isDelayEnded = true; 10719 this.tryStartDrag(ev); 10720 }; 10721 FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) { 10722 this.isDistanceSurpassed = true; 10723 this.tryStartDrag(ev); 10724 }; 10725 FeaturefulElementDragging.prototype.tryStartDrag = function (ev) { 10726 if (this.isDelayEnded && this.isDistanceSurpassed) { 10727 if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) { 10728 this.isDragging = true; 10729 this.mirrorNeedsRevert = false; 10730 this.autoScroller.start(ev.pageX, ev.pageY, this.containerEl); 10731 this.emitter.trigger('dragstart', ev); 10732 if (this.touchScrollAllowed === false) { 10733 this.pointer.cancelTouchScroll(); 10734 } 10735 } 10736 } 10737 }; 10738 FeaturefulElementDragging.prototype.tryStopDrag = function (ev) { 10739 // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events 10740 // that come from the document to fire beforehand. much more convenient this way. 10741 this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev)); 10742 }; 10743 FeaturefulElementDragging.prototype.stopDrag = function (ev) { 10744 this.isDragging = false; 10745 this.emitter.trigger('dragend', ev); 10746 }; 10747 // fill in the implementations... 10748 FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) { 10749 this.pointer.shouldIgnoreMove = bool; 10750 }; 10751 FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) { 10752 this.mirror.setIsVisible(bool); 10753 }; 10754 FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 10755 this.mirrorNeedsRevert = bool; 10756 }; 10757 FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) { 10758 this.autoScroller.isEnabled = bool; 10759 }; 10760 return FeaturefulElementDragging; 10761 }(ElementDragging)); 10762 10763 /* 10764 When this class is instantiated, it records the offset of an element (relative to the document topleft), 10765 and continues to monitor scrolling, updating the cached coordinates if it needs to. 10766 Does not access the DOM after instantiation, so highly performant. 10767 10768 Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element 10769 and an determine if a given point is inside the combined clipping rectangle. 10770 */ 10771 var OffsetTracker = /** @class */ (function () { 10772 function OffsetTracker(el) { 10773 this.origRect = computeRect(el); 10774 // will work fine for divs that have overflow:hidden 10775 this.scrollCaches = getClippingParents(el).map(function (scrollEl) { return new ElementScrollGeomCache(scrollEl, true); }); 10776 } 10777 OffsetTracker.prototype.destroy = function () { 10778 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10779 var scrollCache = _a[_i]; 10780 scrollCache.destroy(); 10781 } 10782 }; 10783 OffsetTracker.prototype.computeLeft = function () { 10784 var left = this.origRect.left; 10785 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10786 var scrollCache = _a[_i]; 10787 left += scrollCache.origScrollLeft - scrollCache.getScrollLeft(); 10788 } 10789 return left; 10790 }; 10791 OffsetTracker.prototype.computeTop = function () { 10792 var top = this.origRect.top; 10793 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10794 var scrollCache = _a[_i]; 10795 top += scrollCache.origScrollTop - scrollCache.getScrollTop(); 10796 } 10797 return top; 10798 }; 10799 OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) { 10800 var point = { left: pageX, top: pageY }; 10801 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10802 var scrollCache = _a[_i];
10803 if (!isIgnoredClipping(scrollCache.getEventTarget()) && 10804 !pointInsideRect(point, scrollCache.clientRect)) { 10805 return false; 10806 } 10807 } 10808 return true; 10809 }; 10810 return OffsetTracker; 10811 }()); 10812 // certain clipping containers should never constrain interactions, like <html> and <body> 10813 // https://github.com/fullcalendar/fullcalendar/issues/3615 10814 function isIgnoredClipping(node) { 10815 var tagName = node.tagName; 10816 return tagName === 'HTML' || tagName === 'BODY'; 10817 } 10818 10819 /* 10820 Tracks movement over multiple droppable areas (aka "hits") 10821 that exist in one or more DateComponents. 10822 Relies on an existing draggable. 10823 10824 emits: 10825 - pointerdown 10826 - dragstart 10827 - hitchange - fires initially, even if not over a hit 10828 - pointerup 10829 - (hitchange - again, to null, if ended over a hit) 10830 - dragend 10831 */ 10832 var HitDragging = /** @class */ (function () { 10833 function HitDragging(dragging, droppableStore) { 10834 var _this = this; 10835 // options that can be set by caller 10836 this.useSubjectCenter = false; 10837 this.requireInitial = true; // if doesn't start out on a hit, won't emit any events 10838 this.initialHit = null; 10839 this.movingHit = null; 10840 this.finalHit = null; // won't ever be populated if shouldIgnoreMove 10841 this.handlePointerDown = function (ev) { 10842 var dragging = _this.dragging; 10843 _this.initialHit = null; 10844 _this.movingHit = null; 10845 _this.finalHit = null; 10846 _this.prepareHits(); 10847 _this.processFirstCoord(ev); 10848 if (_this.initialHit || !_this.requireInitial) { 10849 dragging.setIgnoreMove(false);
10850 // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :( 10851 _this.emitter.trigger('pointerdown', ev); 10852 } 10853 else { 10854 dragging.setIgnoreMove(true); 10855 } 10856 }; 10857 this.handleDragStart = function (ev) { 10858 _this.emitter.trigger('dragstart', ev); 10859 _this.handleMove(ev, true); // force = fire even if initially null 10860 }; 10861 this.handleDragMove = function (ev) { 10862 _this.emitter.trigger('dragmove', ev); 10863 _this.handleMove(ev); 10864 }; 10865 this.handlePointerUp = function (ev) { 10866 _this.releaseHits(); 10867 _this.emitter.trigger('pointerup', ev); 10868 }; 10869 this.handleDragEnd = function (ev) { 10870 if (_this.movingHit) { 10871 _this.emitter.trigger('hitupdate', null, true, ev); 10872 } 10873 _this.finalHit = _this.movingHit; 10874 _this.movingHit = null; 10875 _this.emitter.trigger('dragend', ev); 10876 }; 10877 this.droppableStore = droppableStore; 10878 dragging.emitter.on('pointerdown', this.handlePointerDown); 10879 dragging.emitter.on('dragstart', this.handleDragStart); 10880 dragging.emitter.on('dragmove', this.handleDragMove); 10881 dragging.emitter.on('pointerup', this.handlePointerUp); 10882 dragging.emitter.on('dragend', this.handleDragEnd); 10883 this.dragging = dragging; 10884 this.emitter = new Emitter(); 10885 } 10886 // sets initialHit 10887 // sets coordAdjust 10888 HitDragging.prototype.processFirstCoord = function (ev) { 10889 var origPoint = { left: ev.pageX, top: ev.pageY }; 10890 var adjustedPoint = origPoint; 10891 var subjectEl = ev.subjectEl; 10892 var subjectRect; 10893 if (subjectEl instanceof HTMLElement) { // i.e. not a Document/ShadowRoot 10894 subjectRect = computeRect(subjectEl); 10895 adjustedPoint = constrainPoint(adjustedPoint, subjectRect); 10896 } 10897 var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top); 10898 if (initialHit) { 10899 if (this.useSubjectCenter && subjectRect) { 10900 var slicedSubjectRect = intersectRects(subjectRect, initialHit.rect); 10901 if (slicedSubjectRect) { 10902 adjustedPoint = getRectCenter(slicedSubjectRect); 10903 } 10904 } 10905 this.coordAdjust = diffPoints(adjustedPoint, origPoint); 10906 } 10907 else { 10908 this.coordAdjust = { left: 0, top: 0 }; 10909 } 10910 }; 10911 HitDragging.prototype.handleMove = function (ev, forceHandle) { 10912 var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top); 10913 if (forceHandle || !isHitsEqual(this.movingHit, hit)) { 10914 this.movingHit = hit; 10915 this.emitter.trigger('hitupdate', hit, false, ev); 10916 } 10917 }; 10918 HitDragging.prototype.prepareHits = function () { 10919 this.offsetTrackers = mapHash(this.droppableStore, function (interactionSettings) { 10920 interactionSettings.component.prepareHits(); 10921 return new OffsetTracker(interactionSettings.el); 10922 }); 10923 }; 10924 HitDragging.prototype.releaseHits = function () { 10925 var offsetTrackers = this.offsetTrackers; 10926 for (var id in offsetTrackers) { 10927 offsetTrackers[id].destroy(); 10928 } 10929 this.offsetTrackers = {}; 10930 }; 10931 HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) { 10932 var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers; 10933 var bestHit = null; 10934 for (var id in droppableStore) { 10935 var component = droppableStore[id].component; 10936 var offsetTracker = offsetTrackers[id]; 10937 if (offsetTracker && // wasn't destroyed mid-drag 10938 offsetTracker.isWithinClipping(offsetLeft, offsetTop)) { 10939 var originLeft = offsetTracker.computeLeft(); 10940 var originTop = offsetTracker.computeTop(); 10941 var positionLeft = offsetLeft - originLeft; 10942 var positionTop = offsetTop - originTop; 10943 var origRect = offsetTracker.origRect; 10944 var width = origRect.right - origRect.left; 10945 var height = origRect.bottom - origRect.top; 10946 if ( 10947 // must be within the element's bounds 10948 positionLeft >= 0 && positionLeft < width && 10949 positionTop >= 0 && positionTop < height) { 10950 var hit = component.queryHit(positionLeft, positionTop, width, height); 10951 if (hit && ( 10952 // make sure the hit is within activeRange, meaning it's not a dead cell 10953 rangeContainsRange(hit.dateProfile.activeRange, hit.dateSpan.range)) && 10954 (!bestHit || hit.layer > bestHit.layer)) { 10955 hit.componentId = id; 10956 hit.context = component.context; 10957 // TODO: better way to re-orient rectangle 10958 hit.rect.left += originLeft; 10959 hit.rect.right += originLeft; 10960 hit.rect.top += originTop; 10961 hit.rect.bottom += originTop; 10962 bestHit = hit; 10963 } 10964 } 10965 } 10966 } 10967 return bestHit; 10968 }; 10969 return HitDragging; 10970 }()); 10971 function isHitsEqual(hit0, hit1) { 10972 if (!hit0 && !hit1) { 10973 return true; 10974 } 10975 if (Boolean(hit0) !== Boolean(hit1)) { 10976 return false;
10977 } 10978 return isDateSpansEqual(hit0.dateSpan, hit1.dateSpan); 10979 } 10980 10981 function buildDatePointApiWithContext(dateSpan, context) { 10982 var props = {}; 10983 for (var _i = 0, _a = context.pluginHooks.datePointTransforms; _i < _a.length; _i++) { 10984 var transform = _a[_i]; 10985 __assign(props, transform(dateSpan, context)); 10986 } 10987 __assign(props, buildDatePointApi(dateSpan, context.dateEnv)); 10988 return props; 10989 } 10990 function buildDatePointApi(span, dateEnv) { 10991 return { 10992 date: dateEnv.toDate(span.range.start), 10993 dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }), 10994 allDay: span.allDay, 10995 }; 10996 } 10997 10998 /* 10999 Monitors when the user clicks on a specific date/time of a component. 11000 A pointerdown+pointerup on the same "hit" constitutes a click. 11001 */ 11002 var DateClicking = /** @class */ (function (_super) { 11003 __extends(DateClicking, _super); 11004 function DateClicking(settings) { 11005 var _this = _super.call(this, settings) || this; 11006 _this.handlePointerDown = function (pev) { 11007 var dragging = _this.dragging; 11008 var downEl = pev.origEvent.target; 11009 // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired 11010 dragging.setIgnoreMove(!_this.component.isValidDateDownEl(downEl)); 11011 }; 11012 // won't even fire if moving was ignored 11013 _this.handleDragEnd = function (ev) { 11014 var component = _this.component; 11015 var pointer = _this.dragging.pointer; 11016 if (!pointer.wasTouchScroll) { 11017 var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit; 11018 if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) { 11019 var context = component.context; 11020 var arg = __assign(__assign({}, buildDatePointApiWithContext(initialHit.dateSpan, context)), { dayEl: initialHit.dayEl, jsEvent: ev.origEvent, view: context.viewApi || context.calendarApi.view }); 11021 context.emitter.trigger('dateClick', arg); 11022 } 11023 } 11024 }; 11025 // we DO want to watch pointer moves because otherwise finalHit won't get populated 11026 _this.dragging = new FeaturefulElementDragging(settings.el); 11027 _this.dragging.autoScroller.isEnabled = false; 11028 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 11029 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11030 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11031 return _this; 11032 } 11033 DateClicking.prototype.destroy = function () { 11034 this.dragging.destroy(); 11035 }; 11036 return DateClicking; 11037 }(Interaction)); 11038 11039 /* 11040 Tracks when the user selects a portion of time of a component, 11041 constituted by a drag over date cells, with a possible delay at the beginning of the drag. 11042 */ 11043 var DateSelecting = /** @class */ (function (_super) { 11044 __extends(DateSelecting, _super); 11045 function DateSelecting(settings) { 11046 var _this = _super.call(this, settings) || this; 11047 _this.dragSelection = null; 11048 _this.handlePointerDown = function (ev) { 11049 var _a = _this, component = _a.component, dragging = _a.dragging; 11050 var options = component.context.options; 11051 var canSelect = options.selectable && 11052 component.isValidDateDownEl(ev.origEvent.target); 11053 // don't bother to watch expensive moves if component won't do selection 11054 dragging.setIgnoreMove(!canSelect); 11055 // if touch, require user to hold down 11056 dragging.delay = ev.isTouch ? getComponentTouchDelay$1(component) : null; 11057 }; 11058 _this.handleDragStart = function (ev) { 11059 _this.component.context.calendarApi.unselect(ev); // unselect previous selections 11060 }; 11061 _this.handleHitUpdate = function (hit, isFinal) { 11062 var context = _this.component.context; 11063 var dragSelection = null; 11064 var isInvalid = false;
11065 if (hit) { 11066 var initialHit = _this.hitDragging.initialHit; 11067 var disallowed = hit.componentId === initialHit.componentId 11068 && _this.isHitComboAllowed 11069 && !_this.isHitComboAllowed(initialHit, hit); 11070 if (!disallowed) { 11071 dragSelection = joinHitsIntoSelection(initialHit, hit, context.pluginHooks.dateSelectionTransformers); 11072 } 11073 if (!dragSelection || !isDateSelectionValid(dragSelection, hit.dateProfile, context)) { 11074 isInvalid = true; 11075 dragSelection = null; 11076 } 11077 } 11078 if (dragSelection) { 11079 context.dispatch({ type: 'SELECT_DATES', selection: dragSelection }); 11080 } 11081 else if (!isFinal) { // only unselect if moved away while dragging 11082 context.dispatch({ type: 'UNSELECT_DATES' }); 11083 } 11084 if (!isInvalid) { 11085 enableCursor(); 11086 } 11087 else { 11088 disableCursor(); 11089 } 11090 if (!isFinal) { 11091 _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging 11092 } 11093 }; 11094 _this.handlePointerUp = function (pev) { 11095 if (_this.dragSelection) { 11096 // selection is already rendered, so just need to report selection 11097 triggerDateSelect(_this.dragSelection, pev, _this.component.context); 11098 _this.dragSelection = null; 11099 } 11100 }; 11101 var component = settings.component; 11102 var options = component.context.options; 11103 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 11104 dragging.touchScrollAllowed = false; 11105 dragging.minDistance = options.selectMinDistance || 0; 11106 dragging.autoScroller.isEnabled = options.dragScroll; 11107 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 11108 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11109 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11110 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11111 hitDragging.emitter.on('pointerup', _this.handlePointerUp); 11112 return _this; 11113 } 11114 DateSelecting.prototype.destroy = function () { 11115 this.dragging.destroy(); 11116 }; 11117 return DateSelecting; 11118 }(Interaction)); 11119 function getComponentTouchDelay$1(component) { 11120 var options = component.context.options; 11121 var delay = options.selectLongPressDelay; 11122 if (delay == null) { 11123 delay = options.longPressDelay; 11124 } 11125 return delay; 11126 } 11127 function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) { 11128 var dateSpan0 = hit0.dateSpan; 11129 var dateSpan1 = hit1.dateSpan; 11130 var ms = [ 11131 dateSpan0.range.start, 11132 dateSpan0.range.end, 11133 dateSpan1.range.start, 11134 dateSpan1.range.end, 11135 ]; 11136 ms.sort(compareNumbers); 11137 var props = {}; 11138 for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) { 11139 var transformer = dateSelectionTransformers_1[_i]; 11140 var res = transformer(hit0, hit1); 11141 if (res === false) { 11142 return null; 11143 } 11144 if (res) { 11145 __assign(props, res); 11146 } 11147 } 11148 props.range = { start: ms[0], end: ms[3] }; 11149 props.allDay = dateSpan0.allDay; 11150 return props; 11151 } 11152 11153 var EventDragging = /** @class */ (function (_super) { 11154 __extends(EventDragging, _super); 11155 function EventDragging(settings) { 11156 var _this = _super.call(this, settings) || this; 11157 // internal state 11158 _this.subjectEl = null; 11159 _this.subjectSeg = null; // the seg being selected/dragged 11160 _this.isDragging = false;
11161 _this.eventRange = null; 11162 _this.relevantEvents = null; // the events being dragged 11163 _this.receivingContext = null; 11164 _this.validMutation = null; 11165 _this.mutatedRelevantEvents = null; 11166 _this.handlePointerDown = function (ev) { 11167 var origTarget = ev.origEvent.target; 11168 var _a = _this, component = _a.component, dragging = _a.dragging; 11169 var mirror = dragging.mirror; 11170 var options = component.context.options; 11171 var initialContext = component.context; 11172 _this.subjectEl = ev.subjectEl; 11173 var subjectSeg = _this.subjectSeg = getElSeg(ev.subjectEl); 11174 var eventRange = _this.eventRange = subjectSeg.eventRange; 11175 var eventInstanceId = eventRange.instance.instanceId; 11176 _this.relevantEvents = getRelevantEvents(initialContext.getCurrentData().eventStore, eventInstanceId); 11177 dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance; 11178 dragging.delay = 11179 // only do a touch delay if touch and this event hasn't been selected yet 11180 (ev.isTouch && eventInstanceId !== component.props.eventSelection) ? 11181 getComponentTouchDelay(component) : 11182 null; 11183 if (options.fixedMirrorParent) { 11184 mirror.parentNode = options.fixedMirrorParent; 11185 } 11186 else { 11187 mirror.parentNode = elementClosest(origTarget, '.fc'); 11188 } 11189 mirror.revertDuration = options.dragRevertDuration; 11190 var isValid = component.isValidSegDownEl(origTarget) && 11191 !elementClosest(origTarget, '.fc-event-resizer'); // NOT on a resizer 11192 dragging.setIgnoreMove(!isValid); 11193 // disable dragging for elements that are resizable (ie, selectable) 11194 // but are not draggable 11195 _this.isDragging = isValid && 11196 ev.subjectEl.classList.contains('fc-event-draggable'); 11197 }; 11198 _this.handleDragStart = function (ev) { 11199 var initialContext = _this.component.context; 11200 var eventRange = _this.eventRange; 11201 var eventInstanceId = eventRange.instance.instanceId; 11202 if (ev.isTouch) { 11203 // need to select a different event? 11204 if (eventInstanceId !== _this.component.props.eventSelection) { 11205 initialContext.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId }); 11206 } 11207 } 11208 else { 11209 // if now using mouse, but was previous touch interaction, clear selected event 11210 initialContext.dispatch({ type: 'UNSELECT_EVENT' }); 11211 } 11212 if (_this.isDragging) { 11213 initialContext.calendarApi.unselect(ev); // unselect *date* selection 11214 initialContext.emitter.trigger('eventDragStart', { 11215 el: _this.subjectEl, 11216 event: new EventApi(initialContext, eventRange.def, eventRange.instance), 11217 jsEvent: ev.origEvent, 11218 view: initialContext.viewApi, 11219 }); 11220 } 11221 }; 11222 _this.handleHitUpdate = function (hit, isFinal) { 11223 if (!_this.isDragging) { 11224 return; 11225 } 11226 var relevantEvents = _this.relevantEvents; 11227 var initialHit = _this.hitDragging.initialHit; 11228 var initialContext = _this.component.context; 11229 // states based on new hit 11230 var receivingContext = null; 11231 var mutation = null; 11232 var mutatedRelevantEvents = null; 11233 var isInvalid = false; 11234 var interaction = { 11235 affectedEvents: relevantEvents, 11236 mutatedEvents: createEmptyEventStore(), 11237 isEvent: true, 11238 }; 11239 if (hit) { 11240 receivingContext = hit.context; 11241 var receivingOptions = receivingContext.options; 11242 if (initialContext === receivingContext || 11243 (receivingOptions.editable && receivingOptions.droppable)) { 11244 mutation = computeEventMutation(initialHit, hit, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers); 11245 if (mutation) { 11246 mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, receivingContext.getCurrentData().eventUiBases, mutation, receivingContext); 11247 interaction.mutatedEvents = mutatedRelevantEvents; 11248 if (!isInteractionValid(interaction, hit.dateProfile, receivingContext)) { 11249 isInvalid = true; 11250 mutation = null; 11251 mutatedRelevantEvents = null; 11252 interaction.mutatedEvents = createEmptyEventStore(); 11253 } 11254 } 11255 } 11256 else { 11257 receivingContext = null; 11258 } 11259 } 11260 _this.displayDrag(receivingContext, interaction); 11261 if (!isInvalid) {
11262 enableCursor(); 11263 } 11264 else { 11265 disableCursor(); 11266 } 11267 if (!isFinal) { 11268 if (initialContext === receivingContext && // TODO: write test for this 11269 isHitsEqual(initialHit, hit)) { 11270 mutation = null; 11271 } 11272 _this.dragging.setMirrorNeedsRevert(!mutation); 11273 // render the mirror if no already-rendered mirror 11274 // TODO: wish we could somehow wait for dispatch to guarantee render 11275 _this.dragging.setMirrorIsVisible(!hit || !getElRoot(_this.subjectEl).querySelector('.fc-event-mirror')); 11276 // assign states based on new hit 11277 _this.receivingContext = receivingContext; 11278 _this.validMutation = mutation; 11279 _this.mutatedRelevantEvents = mutatedRelevantEvents; 11280 } 11281 }; 11282 _this.handlePointerUp = function () { 11283 if (!_this.isDragging) { 11284 _this.cleanup(); // because handleDragEnd won't fire 11285 } 11286 }; 11287 _this.handleDragEnd = function (ev) { 11288 if (_this.isDragging) { 11289 var initialContext_1 = _this.component.context; 11290 var initialView = initialContext_1.viewApi; 11291 var _a = _this, receivingContext_1 = _a.receivingContext, validMutation = _a.validMutation; 11292 var eventDef = _this.eventRange.def; 11293 var eventInstance = _this.eventRange.instance; 11294 var eventApi = new EventApi(initialContext_1, eventDef, eventInstance); 11295 var relevantEvents_1 = _this.relevantEvents; 11296 var mutatedRelevantEvents_1 = _this.mutatedRelevantEvents; 11297 var finalHit = _this.hitDragging.finalHit; 11298 _this.clearDrag(); // must happen after revert animation 11299 initialContext_1.emitter.trigger('eventDragStop', { 11300 el: _this.subjectEl, 11301 event: eventApi, 11302 jsEvent: ev.origEvent, 11303 view: initialView, 11304 }); 11305 if (validMutation) { 11306 // dropped within same calendar 11307 if (receivingContext_1 === initialContext_1) { 11308 var updatedEventApi = new EventApi(initialContext_1, mutatedRelevantEvents_1.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents_1.instances[eventInstance.instanceId] : null); 11309 initialContext_1.dispatch({ 11310 type: 'MERGE_EVENTS', 11311 eventStore: mutatedRelevantEvents_1, 11312 }); 11313 var eventChangeArg = { 11314 oldEvent: eventApi, 11315 event: updatedEventApi, 11316 relatedEvents: buildEventApis(mutatedRelevantEvents_1, initialContext_1, eventInstance), 11317 revert: function () { 11318 initialContext_1.dispatch({ 11319 type: 'MERGE_EVENTS', 11320 eventStore: relevantEvents_1, // the pre-change data 11321 }); 11322 }, 11323 }; 11324 var transformed = {}; 11325 for (var _i = 0, _b = initialContext_1.getCurrentData().pluginHooks.eventDropTransformers; _i < _b.length; _i++) { 11326 var transformer = _b[_i]; 11327 __assign(transformed, transformer(validMutation, initialContext_1)); 11328 } 11329 initialContext_1.emitter.trigger('eventDrop', __assign(__assign(__assign({}, eventChangeArg), transformed), { el: ev.subjectEl, delta: validMutation.datesDelta, jsEvent: ev.origEvent, view: initialView })); 11330 initialContext_1.emitter.trigger('eventChange', eventChangeArg); 11331 // dropped in different calendar 11332 } 11333 else if (receivingContext_1) { 11334 var eventRemoveArg = { 11335 event: eventApi, 11336 relatedEvents: buildEventApis(relevantEvents_1, initialContext_1, eventInstance), 11337 revert: function () { 11338 initialContext_1.dispatch({ 11339 type: 'MERGE_EVENTS', 11340 eventStore: relevantEvents_1, 11341 }); 11342 }, 11343 }; 11344 initialContext_1.emitter.trigger('eventLeave', __assign(__assign({}, eventRemoveArg), { draggedEl: ev.subjectEl, view: initialView })); 11345 initialContext_1.dispatch({
11346 type: 'REMOVE_EVENTS', 11347 eventStore: relevantEvents_1, 11348 }); 11349 initialContext_1.emitter.trigger('eventRemove', eventRemoveArg); 11350 var addedEventDef = mutatedRelevantEvents_1.defs[eventDef.defId]; 11351 var addedEventInstance = mutatedRelevantEvents_1.instances[eventInstance.instanceId]; 11352 var addedEventApi = new EventApi(receivingContext_1, addedEventDef, addedEventInstance); 11353 receivingContext_1.dispatch({ 11354 type: 'MERGE_EVENTS', 11355 eventStore: mutatedRelevantEvents_1, 11356 }); 11357 var eventAddArg = { 11358 event: addedEventApi, 11359 relatedEvents: buildEventApis(mutatedRelevantEvents_1, receivingContext_1, addedEventInstance), 11360 revert: function () { 11361 receivingContext_1.dispatch({ 11362 type: 'REMOVE_EVENTS', 11363 eventStore: mutatedRelevantEvents_1, 11364 }); 11365 }, 11366 }; 11367 receivingContext_1.emitter.trigger('eventAdd', eventAddArg); 11368 if (ev.isTouch) { 11369 receivingContext_1.dispatch({ 11370 type: 'SELECT_EVENT', 11371 eventInstanceId: eventInstance.instanceId, 11372 }); 11373 } 11374 receivingContext_1.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext_1)), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.context.viewApi })); 11375 receivingContext_1.emitter.trigger('eventReceive', __assign(__assign({}, eventAddArg), { draggedEl: ev.subjectEl, view: finalHit.context.viewApi })); 11376 } 11377 } 11378 else { 11379 initialContext_1.emitter.trigger('_noEventDrop'); 11380 } 11381 } 11382 _this.cleanup(); 11383 }; 11384 var component = _this.component; 11385 var options = component.context.options; 11386 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 11387 dragging.pointer.selector = EventDragging.SELECTOR; 11388 dragging.touchScrollAllowed = false; 11389 dragging.autoScroller.isEnabled = options.dragScroll; 11390 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsStore); 11391 hitDragging.useSubjectCenter = settings.useEventCenter; 11392 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11393 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11394 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11395 hitDragging.emitter.on('pointerup', _this.handlePointerUp); 11396 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11397 return _this; 11398 } 11399 EventDragging.prototype.destroy = function () { 11400 this.dragging.destroy(); 11401 }; 11402 // render a drag state on the next receivingCalendar 11403 EventDragging.prototype.displayDrag = function (nextContext, state) { 11404 var initialContext = this.component.context; 11405 var prevContext = this.receivingContext; 11406 // does the previous calendar need to be cleared? 11407 if (prevContext && prevContext !== nextContext) { 11408 // does the initial calendar need to be cleared? 11409 // if so, don't clear all the way. we still need to to hide the affectedEvents 11410 if (prevContext === initialContext) { 11411 prevContext.dispatch({ 11412 type: 'SET_EVENT_DRAG', 11413 state: { 11414 affectedEvents: state.affectedEvents, 11415 mutatedEvents: createEmptyEventStore(), 11416 isEvent: true, 11417 }, 11418 }); 11419 // completely clear the old calendar if it wasn't the initial 11420 } 11421 else { 11422 prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11423 } 11424 } 11425 if (nextContext) { 11426 nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state }); 11427 } 11428 }; 11429 EventDragging.prototype.clearDrag = function () { 11430 var initialCalendar = this.component.context; 11431 var receivingContext = this.receivingContext; 11432 if (receivingContext) { 11433 receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11434 } 11435 // the initial calendar might have an dummy drag state from displayDrag 11436 if (initialCalendar !== receivingContext) { 11437 initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11438 } 11439 }; 11440 EventDragging.prototype.cleanup = function () { 11441 this.subjectSeg = null; 11442 this.isDragging = false;
11443 this.eventRange = null; 11444 this.relevantEvents = null; 11445 this.receivingContext = null; 11446 this.validMutation = null; 11447 this.mutatedRelevantEvents = null; 11448 }; 11449 // TODO: test this in IE11 11450 // QUESTION: why do we need it on the resizable??? 11451 EventDragging.SELECTOR = '.fc-event-draggable, .fc-event-resizable'; 11452 return EventDragging; 11453 }(Interaction)); 11454 function computeEventMutation(hit0, hit1, massagers) { 11455 var dateSpan0 = hit0.dateSpan; 11456 var dateSpan1 = hit1.dateSpan; 11457 var date0 = dateSpan0.range.start; 11458 var date1 = dateSpan1.range.start; 11459 var standardProps = {}; 11460 if (dateSpan0.allDay !== dateSpan1.allDay) { 11461 standardProps.allDay = dateSpan1.allDay; 11462 standardProps.hasEnd = hit1.context.options.allDayMaintainDuration; 11463 if (dateSpan1.allDay) { 11464 // means date1 is already start-of-day, 11465 // but date0 needs to be converted 11466 date0 = startOfDay(date0); 11467 } 11468 } 11469 var delta = diffDates(date0, date1, hit0.context.dateEnv, hit0.componentId === hit1.componentId ? 11470 hit0.largeUnit : 11471 null); 11472 if (delta.milliseconds) { // has hours/minutes/seconds 11473 standardProps.allDay = false; 11474 } 11475 var mutation = { 11476 datesDelta: delta, 11477 standardProps: standardProps, 11478 }; 11479 for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) { 11480 var massager = massagers_1[_i]; 11481 massager(mutation, hit0, hit1); 11482 } 11483 return mutation; 11484 } 11485 function getComponentTouchDelay(component) { 11486 var options = component.context.options; 11487 var delay = options.eventLongPressDelay; 11488 if (delay == null) { 11489 delay = options.longPressDelay; 11490 } 11491 return delay; 11492 } 11493 11494 var EventResizing = /** @class */ (function (_super) { 11495 __extends(EventResizing, _super); 11496 function EventResizing(settings) { 11497 var _this = _super.call(this, settings) || this; 11498 // internal state 11499 _this.draggingSegEl = null; 11500 _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg? 11501 _this.eventRange = null; 11502 _this.relevantEvents = null; 11503 _this.validMutation = null; 11504 _this.mutatedRelevantEvents = null; 11505 _this.handlePointerDown = function (ev) { 11506 var component = _this.component; 11507 var segEl = _this.querySegEl(ev); 11508 var seg = getElSeg(segEl); 11509 var eventRange = _this.eventRange = seg.eventRange; 11510 _this.dragging.minDistance = component.context.options.eventDragMinDistance; 11511 // if touch, need to be working with a selected event 11512 _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) || 11513 (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId)); 11514 }; 11515 _this.handleDragStart = function (ev) { 11516 var context = _this.component.context; 11517 var eventRange = _this.eventRange; 11518 _this.relevantEvents = getRelevantEvents(context.getCurrentData().eventStore, _this.eventRange.instance.instanceId); 11519 var segEl = _this.querySegEl(ev); 11520 _this.draggingSegEl = segEl; 11521 _this.draggingSeg = getElSeg(segEl); 11522 context.calendarApi.unselect(); 11523 context.emitter.trigger('eventResizeStart', { 11524 el: segEl, 11525 event: new EventApi(context, eventRange.def, eventRange.instance), 11526 jsEvent: ev.origEvent, 11527 view: context.viewApi, 11528 }); 11529 }; 11530 _this.handleHitUpdate = function (hit, isFinal, ev) { 11531 var context = _this.component.context; 11532 var relevantEvents = _this.relevantEvents; 11533 var initialHit = _this.hitDragging.initialHit; 11534 var eventInstance = _this.eventRange.instance; 11535 var mutation = null; 11536 var mutatedRelevantEvents = null; 11537 var isInvalid = false;
11538 var interaction = { 11539 affectedEvents: relevantEvents, 11540 mutatedEvents: createEmptyEventStore(), 11541 isEvent: true, 11542 }; 11543 if (hit) { 11544 var disallowed = hit.componentId === initialHit.componentId 11545 && _this.isHitComboAllowed 11546 && !_this.isHitComboAllowed(initialHit, hit); 11547 if (!disallowed) { 11548 mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-event-resizer-start'), eventInstance.range); 11549 } 11550 } 11551 if (mutation) { 11552 mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, context.getCurrentData().eventUiBases, mutation, context); 11553 interaction.mutatedEvents = mutatedRelevantEvents; 11554 if (!isInteractionValid(interaction, hit.dateProfile, context)) { 11555 isInvalid = true; 11556 mutation = null; 11557 mutatedRelevantEvents = null; 11558 interaction.mutatedEvents = null; 11559 } 11560 } 11561 if (mutatedRelevantEvents) { 11562 context.dispatch({ 11563 type: 'SET_EVENT_RESIZE', 11564 state: interaction, 11565 }); 11566 } 11567 else { 11568 context.dispatch({ type: 'UNSET_EVENT_RESIZE' }); 11569 } 11570 if (!isInvalid) { 11571 enableCursor(); 11572 } 11573 else { 11574 disableCursor(); 11575 } 11576 if (!isFinal) { 11577 if (mutation && isHitsEqual(initialHit, hit)) { 11578 mutation = null; 11579 } 11580 _this.validMutation = mutation; 11581 _this.mutatedRelevantEvents = mutatedRelevantEvents; 11582 } 11583 }; 11584 _this.handleDragEnd = function (ev) { 11585 var context = _this.component.context; 11586 var eventDef = _this.eventRange.def; 11587 var eventInstance = _this.eventRange.instance; 11588 var eventApi = new EventApi(context, eventDef, eventInstance); 11589 var relevantEvents = _this.relevantEvents; 11590 var mutatedRelevantEvents = _this.mutatedRelevantEvents; 11591 context.emitter.trigger('eventResizeStop', { 11592 el: _this.draggingSegEl, 11593 event: eventApi, 11594 jsEvent: ev.origEvent, 11595 view: context.viewApi, 11596 }); 11597 if (_this.validMutation) { 11598 var updatedEventApi = new EventApi(context, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null); 11599 context.dispatch({ 11600 type: 'MERGE_EVENTS', 11601 eventStore: mutatedRelevantEvents, 11602 }); 11603 var eventChangeArg = { 11604 oldEvent: eventApi, 11605 event: updatedEventApi, 11606 relatedEvents: buildEventApis(mutatedRelevantEvents, context, eventInstance), 11607 revert: function () { 11608 context.dispatch({ 11609 type: 'MERGE_EVENTS', 11610 eventStore: relevantEvents, // the pre-change events 11611 }); 11612 }, 11613 }; 11614 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 })); 11615 context.emitter.trigger('eventChange', eventChangeArg); 11616 } 11617 else { 11618 context.emitter.trigger('_noEventResize'); 11619 } 11620 // reset all internal state 11621 _this.draggingSeg = null; 11622 _this.relevantEvents = null; 11623 _this.validMutation = null; 11624 // okay to keep eventInstance around. useful to set it in handlePointerDown 11625 }; 11626 var component = settings.component; 11627 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 11628 dragging.pointer.selector = '.fc-event-resizer'; 11629 dragging.touchScrollAllowed = false;
11630 dragging.autoScroller.isEnabled = component.context.options.dragScroll; 11631 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 11632 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11633 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11634 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11635 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11636 return _this; 11637 } 11638 EventResizing.prototype.destroy = function () { 11639 this.dragging.destroy(); 11640 }; 11641 EventResizing.prototype.querySegEl = function (ev) { 11642 return elementClosest(ev.subjectEl, '.fc-event'); 11643 }; 11644 return EventResizing; 11645 }(Interaction)); 11646 function computeMutation(hit0, hit1, isFromStart, instanceRange) { 11647 var dateEnv = hit0.context.dateEnv; 11648 var date0 = hit0.dateSpan.range.start; 11649 var date1 = hit1.dateSpan.range.start; 11650 var delta = diffDates(date0, date1, dateEnv, hit0.largeUnit); 11651 if (isFromStart) { 11652 if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) { 11653 return { startDelta: delta }; 11654 } 11655 } 11656 else if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) { 11657 return { endDelta: delta }; 11658 } 11659 return null; 11660 } 11661 11662 var UnselectAuto = /** @class */ (function () { 11663 function UnselectAuto(context) { 11664 var _this = this; 11665 this.context = context; 11666 this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system 11667 this.matchesCancel = false; 11668 this.matchesEvent = false; 11669 this.onSelect = function (selectInfo) { 11670 if (selectInfo.jsEvent) { 11671 _this.isRecentPointerDateSelect = true; 11672 } 11673 }; 11674 this.onDocumentPointerDown = function (pev) { 11675 var unselectCancel = _this.context.options.unselectCancel; 11676 var downEl = getEventTargetViaRoot(pev.origEvent); 11677 _this.matchesCancel = !!elementClosest(downEl, unselectCancel); 11678 _this.matchesEvent = !!elementClosest(downEl, EventDragging.SELECTOR); // interaction started on an event? 11679 }; 11680 this.onDocumentPointerUp = function (pev) { 11681 var context = _this.context; 11682 var documentPointer = _this.documentPointer; 11683 var calendarState = context.getCurrentData(); 11684 // touch-scrolling should never unfocus any type of selection 11685 if (!documentPointer.wasTouchScroll) { 11686 if (calendarState.dateSelection && // an existing date selection? 11687 !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp? 11688 ) { 11689 var unselectAuto = context.options.unselectAuto; 11690 if (unselectAuto && (!unselectAuto || !_this.matchesCancel)) { 11691 context.calendarApi.unselect(pev); 11692 } 11693 } 11694 if (calendarState.eventSelection && // an existing event selected? 11695 !_this.matchesEvent // interaction DIDN'T start on an event 11696 ) { 11697 context.dispatch({ type: 'UNSELECT_EVENT' }); 11698 } 11699 } 11700 _this.isRecentPointerDateSelect = false; 11701 }; 11702 var documentPointer = this.documentPointer = new PointerDragging(document); 11703 documentPointer.shouldIgnoreMove = true; 11704 documentPointer.shouldWatchScroll = false; 11705 documentPointer.emitter.on('pointerdown', this.onDocumentPointerDown); 11706 documentPointer.emitter.on('pointerup', this.onDocumentPointerUp); 11707 /* 11708 TODO: better way to know about whether there was a selection with the pointer 11709 */ 11710 context.emitter.on('select', this.onSelect); 11711 } 11712 UnselectAuto.prototype.destroy = function () { 11713 this.context.emitter.off('select', this.onSelect); 11714 this.documentPointer.destroy(); 11715 }; 11716 return UnselectAuto; 11717 }()); 11718 11719 var OPTION_REFINERS$3 = { 11720 fixedMirrorParent: identity, 11721 }; 11722 var LISTENER_REFINERS = { 11723 dateClick: identity, 11724 eventDragStart: identity, 11725 eventDragStop: identity, 11726 eventDrop: identity, 11727 eventResizeStart: identity, 11728 eventResizeStop: identity, 11729 eventResize: identity, 11730 drop: identity, 11731 eventReceive: identity, 11732 eventLeave: identity, 11733 }; 11734 11735 /* 11736 Given an already instantiated draggable object for one-or-more elements, 11737 Interprets any dragging as an attempt to drag an events that lives outside 11738 of a calendar onto a calendar. 11739 */
11740 var ExternalElementDragging = /** @class */ (function () { 11741 function ExternalElementDragging(dragging, suppliedDragMeta) { 11742 var _this = this; 11743 this.receivingContext = null; 11744 this.droppableEvent = null; // will exist for all drags, even if create:false 11745 this.suppliedDragMeta = null; 11746 this.dragMeta = null; 11747 this.handleDragStart = function (ev) { 11748 _this.dragMeta = _this.buildDragMeta(ev.subjectEl); 11749 }; 11750 this.handleHitUpdate = function (hit, isFinal, ev) { 11751 var dragging = _this.hitDragging.dragging; 11752 var receivingContext = null; 11753 var droppableEvent = null; 11754 var isInvalid = false; 11755 var interaction = { 11756 affectedEvents: createEmptyEventStore(), 11757 mutatedEvents: createEmptyEventStore(), 11758 isEvent: _this.dragMeta.create, 11759 }; 11760 if (hit) { 11761 receivingContext = hit.context; 11762 if (_this.canDropElOnCalendar(ev.subjectEl, receivingContext)) { 11763 droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingContext); 11764 interaction.mutatedEvents = eventTupleToStore(droppableEvent); 11765 isInvalid = !isInteractionValid(interaction, hit.dateProfile, receivingContext); 11766 if (isInvalid) { 11767 interaction.mutatedEvents = createEmptyEventStore(); 11768 droppableEvent = null; 11769 } 11770 } 11771 } 11772 _this.displayDrag(receivingContext, interaction); 11773 // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?) 11774 // TODO: wish we could somehow wait for dispatch to guarantee render 11775 dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-event-mirror')); 11776 if (!isInvalid) { 11777 enableCursor(); 11778 } 11779 else { 11780 disableCursor(); 11781 } 11782 if (!isFinal) { 11783 dragging.setMirrorNeedsRevert(!droppableEvent); 11784 _this.receivingContext = receivingContext; 11785 _this.droppableEvent = droppableEvent; 11786 } 11787 }; 11788 this.handleDragEnd = function (pev) { 11789 var _a = _this, receivingContext = _a.receivingContext, droppableEvent = _a.droppableEvent; 11790 _this.clearDrag(); 11791 if (receivingContext && droppableEvent) { 11792 var finalHit = _this.hitDragging.finalHit; 11793 var finalView = finalHit.context.viewApi; 11794 var dragMeta = _this.dragMeta; 11795 receivingContext.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView })); 11796 if (dragMeta.create) { 11797 var addingEvents_1 = eventTupleToStore(droppableEvent); 11798 receivingContext.dispatch({ 11799 type: 'MERGE_EVENTS', 11800 eventStore: addingEvents_1, 11801 }); 11802 if (pev.isTouch) { 11803 receivingContext.dispatch({ 11804 type: 'SELECT_EVENT', 11805 eventInstanceId: droppableEvent.instance.instanceId, 11806 }); 11807 } 11808 // signal that an external event landed 11809 receivingContext.emitter.trigger('eventReceive', { 11810 event: new EventApi(receivingContext, droppableEvent.def, droppableEvent.instance), 11811 relatedEvents: [], 11812 revert: function () { 11813 receivingContext.dispatch({
11814 type: 'REMOVE_EVENTS', 11815 eventStore: addingEvents_1, 11816 }); 11817 }, 11818 draggedEl: pev.subjectEl, 11819 view: finalView, 11820 }); 11821 } 11822 } 11823 _this.receivingContext = null; 11824 _this.droppableEvent = null; 11825 }; 11826 var hitDragging = this.hitDragging = new HitDragging(dragging, interactionSettingsStore); 11827 hitDragging.requireInitial = false; // will start outside of a component 11828 hitDragging.emitter.on('dragstart', this.handleDragStart); 11829 hitDragging.emitter.on('hitupdate', this.handleHitUpdate); 11830 hitDragging.emitter.on('dragend', this.handleDragEnd); 11831 this.suppliedDragMeta = suppliedDragMeta; 11832 } 11833 ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) { 11834 if (typeof this.suppliedDragMeta === 'object') { 11835 return parseDragMeta(this.suppliedDragMeta); 11836 } 11837 if (typeof this.suppliedDragMeta === 'function') { 11838 return parseDragMeta(this.suppliedDragMeta(subjectEl)); 11839 } 11840 return getDragMetaFromEl(subjectEl); 11841 }; 11842 ExternalElementDragging.prototype.displayDrag = function (nextContext, state) { 11843 var prevContext = this.receivingContext; 11844 if (prevContext && prevContext !== nextContext) { 11845 prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11846 } 11847 if (nextContext) { 11848 nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state }); 11849 } 11850 }; 11851 ExternalElementDragging.prototype.clearDrag = function () { 11852 if (this.receivingContext) { 11853 this.receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11854 } 11855 }; 11856 ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingContext) { 11857 var dropAccept = receivingContext.options.dropAccept; 11858 if (typeof dropAccept === 'function') { 11859 return dropAccept.call(receivingContext.calendarApi, el); 11860 } 11861 if (typeof dropAccept === 'string' && dropAccept) { 11862 return Boolean(elementMatches(el, dropAccept)); 11863 } 11864 return true; 11865 }; 11866 return ExternalElementDragging; 11867 }()); 11868 // Utils for computing event store from the DragMeta 11869 // ---------------------------------------------------------------------------------------------------- 11870 function computeEventForDateSpan(dateSpan, dragMeta, context) { 11871 var defProps = __assign({}, dragMeta.leftoverProps); 11872 for (var _i = 0, _a = context.pluginHooks.externalDefTransforms; _i < _a.length; _i++) { 11873 var transform = _a[_i]; 11874 __assign(defProps, transform(dateSpan, dragMeta)); 11875 } 11876 var _b = refineEventDef(defProps, context), refined = _b.refined, extra = _b.extra; 11877 var def = parseEventDef(refined, extra, dragMeta.sourceId, dateSpan.allDay, context.options.forceEventDuration || Boolean(dragMeta.duration), // hasEnd 11878 context); 11879 var start = dateSpan.range.start; 11880 // only rely on time info if drop zone is all-day, 11881 // otherwise, we already know the time 11882 if (dateSpan.allDay && dragMeta.startTime) { 11883 start = context.dateEnv.add(start, dragMeta.startTime); 11884 } 11885 var end = dragMeta.duration ? 11886 context.dateEnv.add(start, dragMeta.duration) : 11887 getDefaultEventEnd(dateSpan.allDay, start, context); 11888 var instance = createEventInstance(def.defId, { start: start, end: end }); 11889 return { def: def, instance: instance }; 11890 } 11891 // Utils for extracting data from element 11892 // ---------------------------------------------------------------------------------------------------- 11893 function getDragMetaFromEl(el) { 11894 var str = getEmbeddedElData(el, 'event'); 11895 var obj = str ? 11896 JSON.parse(str) : 11897 { create: false }; // if no embedded data, assume no event creation 11898 return parseDragMeta(obj); 11899 } 11900 config.dataAttrPrefix = ''; 11901 function getEmbeddedElData(el, name) { 11902 var prefix = config.dataAttrPrefix; 11903 var prefixedName = (prefix ? prefix + '-' : '') + name; 11904 return el.getAttribute('data-' + prefixedName) || ''; 11905 } 11906 11907 /* 11908 Makes an element (that is *external* to any calendar) draggable. 11909 Can pass in data that determines how an event will be created when dropped onto a calendar. 11910 Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system. 11911 */
11912 var ExternalDraggable = /** @class */ (function () { 11913 function ExternalDraggable(el, settings) { 11914 var _this = this; 11915 if (settings === void 0) { settings = {}; } 11916 this.handlePointerDown = function (ev) { 11917 var dragging = _this.dragging; 11918 var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay; 11919 dragging.minDistance = 11920 minDistance != null ? 11921 minDistance : 11922 (ev.isTouch ? 0 : BASE_OPTION_DEFAULTS.eventDragMinDistance); 11923 dragging.delay = 11924 ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv 11925 (longPressDelay != null ? longPressDelay : BASE_OPTION_DEFAULTS.longPressDelay) : 11926 0; 11927 }; 11928 this.handleDragStart = function (ev) { 11929 if (ev.isTouch && 11930 _this.dragging.delay && 11931 ev.subjectEl.classList.contains('fc-event')) { 11932 _this.dragging.mirror.getMirrorEl().classList.add('fc-event-selected'); 11933 } 11934 }; 11935 this.settings = settings; 11936 var dragging = this.dragging = new FeaturefulElementDragging(el); 11937 dragging.touchScrollAllowed = false; 11938 if (settings.itemSelector != null) { 11939 dragging.pointer.selector = settings.itemSelector; 11940 } 11941 if (settings.appendTo != null) { 11942 dragging.mirror.parentNode = settings.appendTo; // TODO: write tests 11943 } 11944 dragging.emitter.on('pointerdown', this.handlePointerDown); 11945 dragging.emitter.on('dragstart', this.handleDragStart); 11946 new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new 11947 } 11948 ExternalDraggable.prototype.destroy = function () { 11949 this.dragging.destroy(); 11950 }; 11951 return ExternalDraggable; 11952 }()); 11953 11954 /* 11955 Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements. 11956 The third-party system is responsible for drawing the visuals effects of the drag. 11957 This class simply monitors for pointer movements and fires events. 11958 It also has the ability to hide the moving element (the "mirror") during the drag. 11959 */ 11960 var InferredElementDragging = /** @class */ (function (_super) { 11961 __extends(InferredElementDragging, _super); 11962 function InferredElementDragging(containerEl) { 11963 var _this = _super.call(this, containerEl) || this; 11964 _this.shouldIgnoreMove = false; 11965 _this.mirrorSelector = ''; 11966 _this.currentMirrorEl = null; 11967 _this.handlePointerDown = function (ev) { 11968 _this.emitter.trigger('pointerdown', ev); 11969 if (!_this.shouldIgnoreMove) { 11970 // fire dragstart right away. does not support delay or min-distance 11971 _this.emitter.trigger('dragstart', ev); 11972 } 11973 }; 11974 _this.handlePointerMove = function (ev) { 11975 if (!_this.shouldIgnoreMove) { 11976 _this.emitter.trigger('dragmove', ev); 11977 } 11978 }; 11979 _this.handlePointerUp = function (ev) { 11980 _this.emitter.trigger('pointerup', ev); 11981 if (!_this.shouldIgnoreMove) { 11982 // fire dragend right away. does not support a revert animation 11983 _this.emitter.trigger('dragend', ev); 11984 } 11985 }; 11986 var pointer = _this.pointer = new PointerDragging(containerEl); 11987 pointer.emitter.on('pointerdown', _this.handlePointerDown); 11988 pointer.emitter.on('pointermove', _this.handlePointerMove); 11989 pointer.emitter.on('pointerup', _this.handlePointerUp); 11990 return _this; 11991 } 11992 InferredElementDragging.prototype.destroy = function () { 11993 this.pointer.destroy(); 11994 }; 11995 InferredElementDragging.prototype.setIgnoreMove = function (bool) { 11996 this.shouldIgnoreMove = bool; 11997 }; 11998 InferredElementDragging.prototype.setMirrorIsVisible = function (bool) { 11999 if (bool) { 12000 // restore a previously hidden element. 12001 // use the reference in case the selector class has already been removed. 12002 if (this.currentMirrorEl) { 12003 this.currentMirrorEl.style.visibility = ''; 12004 this.currentMirrorEl = null; 12005 } 12006 } 12007 else { 12008 var mirrorEl = this.mirrorSelector 12009 // TODO: somehow query FullCalendars WITHIN shadow-roots 12010 ? document.querySelector(this.mirrorSelector) 12011 : null; 12012 if (mirrorEl) { 12013 this.currentMirrorEl = mirrorEl; 12014 mirrorEl.style.visibility = 'hidden'; 12015 } 12016 } 12017 }; 12018 return InferredElementDragging; 12019 }(ElementDragging)); 12020 12021 /* 12022 Bridges third-party drag-n-drop systems with FullCalendar. 12023 Must be instantiated and destroyed by caller. 12024 */ 12025 var ThirdPartyDraggable = /** @class */ (function () { 12026 function ThirdPartyDraggable(containerOrSettings, settings) { 12027 var containerEl = document; 12028 if ( 12029 // wish we could just test instanceof EventTarget, but doesn't work in IE11 12030 containerOrSettings === document || 12031 containerOrSettings instanceof Element) { 12032 containerEl = containerOrSettings; 12033 settings = settings || {}; 12034 } 12035 else { 12036 settings = (containerOrSettings || {}); 12037 } 12038 var dragging = this.dragging = new InferredElementDragging(containerEl); 12039 if (typeof settings.itemSelector === 'string') { 12040 dragging.pointer.selector = settings.itemSelector; 12041 } 12042 else if (containerEl === document) { 12043 dragging.pointer.selector = '[data-event]'; 12044 } 12045 if (typeof settings.mirrorSelector === 'string') { 12046 dragging.mirrorSelector = settings.mirrorSelector; 12047 } 12048 new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new 12049 } 12050 ThirdPartyDraggable.prototype.destroy = function () { 12051 this.dragging.destroy(); 12052 }; 12053 return ThirdPartyDraggable; 12054 }()); 12055 12056 var interactionPlugin = createPlugin({ 12057 componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing], 12058 calendarInteractions: [UnselectAuto], 12059 elementDraggingImpl: FeaturefulElementDragging, 12060 optionRefiners: OPTION_REFINERS$3, 12061 listenerRefiners: LISTENER_REFINERS, 12062 }); 12063 12064 /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells. 12065 ----------------------------------------------------------------------------------------------------------------------*/ 12066 // It is a manager for a Table subcomponent, which does most of the heavy lifting. 12067 // It is responsible for managing width/height. 12068 var TableView = /** @class */ (function (_super) { 12069 __extends(TableView, _super); 12070 function TableView() { 12071 var _this = _super !== null && _super.apply(this, arguments) || this; 12072 _this.headerElRef = createRef(); 12073 return _this; 12074 } 12075 TableView.prototype.renderSimpleLayout = function (headerRowContent, bodyContent) { 12076 var _a = this, props = _a.props, context = _a.context; 12077 var sections = []; 12078 var stickyHeaderDates = getStickyHeaderDates(context.options); 12079 if (headerRowContent) { 12080 sections.push({ 12081 type: 'header', 12082 key: 'header', 12083 isSticky: stickyHeaderDates, 12084 chunk: { 12085 elRef: this.headerElRef, 12086 tableClassName: 'fc-col-header', 12087 rowContent: headerRowContent, 12088 }, 12089 }); 12090 } 12091 sections.push({ 12092 type: 'body', 12093 key: 'body', 12094 liquid: true, 12095 chunk: { content: bodyContent }, 12096 }); 12097 return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygri
12097d'].concat(classNames).join(' ') }, 12098 createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [] /* TODO: make optional? */, sections: sections }))); })); 12099 }; 12100 TableView.prototype.renderHScrollLayout = function (headerRowContent, bodyContent, colCnt, dayMinWidth) { 12101 var ScrollGrid = this.context.pluginHooks.scrollGridImpl; 12102 if (!ScrollGrid) { 12103 throw new Error('No ScrollGrid implementation'); 12104 } 12105 var _a = this, props = _a.props, context = _a.context; 12106 var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options); 12107 var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options); 12108 var sections = []; 12109 if (headerRowContent) { 12110 sections.push({ 12111 type: 'header', 12112 key: 'header', 12113 isSticky: stickyHeaderDates, 12114 chunks: [{ 12115 key: 'main', 12116 elRef: this.headerElRef, 12117 tableClassName: 'fc-col-header', 12118 rowContent: headerRowContent, 12119 }], 12120 }); 12121 } 12122 sections.push({ 12123 type: 'body', 12124 key: 'body', 12125 liquid: true, 12126 chunks: [{ 12127 key: 'main', 12128 content: bodyContent, 12129 }], 12130 }); 12131 if (stickyFooterScrollbar) { 12132 sections.push({ 12133 type: 'footer', 12134 key: 'footer', 12135 isSticky: true, 12136 chunks: [{ 12137 key: 'main', 12138 content: renderScrollShim, 12139 }], 12140 }); 12141 } 12142 return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygrid'].concat(classNames).join(' ') }, 12143 createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], sections: sections }))); })); 12144 }; 12145 return TableView; 12146 }(DateComponent)); 12147 12148 function splitSegsByRow(segs, rowCnt) { 12149 var byRow = []; 12150 for (var i = 0; i < rowCnt; i += 1) { 12151 byRow[i] = []; 12152 } 12153 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 12154 var seg = segs_1[_i]; 12155 byRow[seg.row].push(seg); 12156 } 12157 return byRow; 12158 } 12159 function splitSegsByFirstCol(segs, colCnt) { 12160 var byCol = []; 12161 for (var i = 0; i < colCnt; i += 1) { 12162 byCol[i] = []; 12163 } 12164 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 12165 var seg = segs_2[_i]; 12166 byCol[seg.firstCol].push(seg); 12167 } 12168 return byCol; 12169 } 12170 function splitInteractionByRow(ui, rowCnt) { 12171 var byRow = []; 12172 if (!ui) { 12173 for (var i = 0; i < rowCnt; i += 1) { 12174 byRow[i] = null; 12175 } 12176 } 12177 else { 12178 for (var i = 0; i < rowCnt; i += 1) { 12179 byRow[i] = { 12180 affectedInstances: ui.affectedInstances, 12181 isEvent: ui.isEvent, 12182 segs: [], 12183 }; 12184 } 12185 for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) { 12186 var seg = _a[_i]; 12187 byRow[seg.row].segs.push(seg); 12188 } 12189 } 12190 return byRow; 12191 } 12192 12193 var TableCellTop = /** @class */ (function (_super) { 12194 __extends(TableCellTop, _super); 12195 function TableCellTop() { 12196 return _super !== null && _super.apply(this, arguments) || this; 12197 } 12198 TableCellTop.prototype.render = function () { 12199 var props = this.props; 12200 var navLinkAttrs = buildNavLinkAttrs(this.context, props.date); 12201 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
12201d-day-top", ref: innerElRef }, 12202 createElement("a", __assign({ id: props.dayNumberId, className: "fc-daygrid-day-number" }, navLinkAttrs), innerContent || createElement(Fragment, null, "\u00A0"))))); })); 12203 }; 12204 return TableCellTop; 12205 }(BaseComponent)); 12206 function renderTopInner(props) { 12207 return props.dayNumberText; 12208 } 12209 12210 var DEFAULT_TABLE_EVENT_TIME_FORMAT = createFormatter({ 12211 hour: 'numeric', 12212 minute: '2-digit', 12213 omitZeroMinute: true, 12214 meridiem: 'narrow', 12215 }); 12216 function hasListItemDisplay(seg) { 12217 var display = seg.eventRange.ui.display; 12218 return display === 'list-item' || (display === 'auto' && 12219 !seg.eventRange.def.allDay && 12220 seg.firstCol === seg.lastCol && // can't be multi-day 12221 seg.isStart && // " 12222 seg.isEnd // " 12223 ); 12224 } 12225 12226 var TableBlockEvent = /** @class */ (function (_super) { 12227 __extends(TableBlockEvent, _super); 12228 function TableBlockEvent() { 12229 return _super !== null && _super.apply(this, arguments) || this; 12230 } 12231 TableBlockEvent.prototype.render = function () { 12232 var props = this.props; 12233 return (createElement(StandardEvent, __assign({}
12233, 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 }))); 12234 }; 12235 return TableBlockEvent; 12236 }(BaseComponent)); 12237 12238 var TableListItemEvent = /** @class */ (function (_super) { 12239 __extends(TableListItemEvent, _super); 12240 function TableListItemEvent() { 12241 return _super !== null && _super.apply(this, arguments) || this; 12242 } 12243 TableListItemEvent.prototype.render = function () { 12244 var _a = this, props = _a.props, context = _a.context; 12245 var timeFormat = context.options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT; 12246 var timeText = buildSegTimeText(props.seg, timeFormat, context, true, props.defaultDisplayEventEnd); 12247 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! 12248 createElement("a", __assign({ className: ['fc-daygrid-event', 'fc-daygri
12248d-dot-event'].concat(classNames).join(' '), ref: rootElRef }, getSegAnchorAttrs(props.seg, context)), innerContent)); })); 12249 }; 12250 return TableListItemEvent; 12251 }(BaseComponent)); 12252 function renderInnerContent$2(innerProps) { 12253 return (createElement(Fragment, null, 12254 createElement("div", { className: "fc-daygrid-event-dot", style: { borderColor: innerProps.borderColor || innerProps.backgroundColor } }), 12255 innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)), 12256 createElement("div", { className: "fc-event-title" }, innerProps.event.title || createElement(Fragment, null, "\u00A0")))); 12257 } 12258 12259 var TableCellMoreLink = /** @class */ (function (_super) { 12260 __extends(TableCellMoreLink, _super); 12261 function TableCellMoreLink() { 12262 var _this = _super !== null && _super.apply(this, arguments) || this; 12263 _this.compileSegs = memoize(compileSegs); 12264 return _this; 12265 } 12266 TableCellMoreLink.prototype.render = function () { 12267 var props = this.props; 12268 var _a = this.compileSegs(props.singlePlacements), allSegs = _a.allSegs, invisibleSegs = _a.invisibleSegs; 12269 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 () { 12270 var isForcedInvisible = (props.eventDrag ? props.eventDrag.affectedInstances : null) || 12271 (props.eventResize ? props.eventResize.affectedInstances : null) || 12272 {}; 12273 return (createElement(Fragment, null, allSegs.map(function (seg) { 12274 var instanceId = seg.eventRange.instance.instanceId; 12275 return (createElement("div", { className: "fc-daygrid-event-harness", key: instanceId, style: { 12276 visibility: isForcedInvisible[instanceId] ? 'hidden' : '', 12277 } }, 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)))))); 12278 }))); 12279 } }, 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)); })); 12280 }; 12281 return TableCellMoreLink; 12282 }(BaseComponent)); 12283 function compileSegs(singlePlacements) { 12284 var allSegs = []; 12285 var invisibleSegs = []; 12286 for (var _i = 0, singlePlacements_1 = singlePlacements; _i < singlePlacements_1.length; _i++) { 12287 var placement = singlePlacements_1[_i]; 12288 allSegs.push(placement.seg); 12289 if (!placement.isVisible) { 12290 invisibleSegs.push(placement.seg); 12291 } 12292 } 12293 return { allSegs: allSegs, invisibleSegs: invisibleSegs }; 12294 } 12295 12296 var DEFAULT_WEEK_NUM_FORMAT$1 = createFormatter({ week: 'narrow' }); 12297 var TableCell = /** @class */ (function (_super) { 12298 __extends(TableCell, _super); 12299 function TableCell() { 12300 var _this = _super !== null && _super.apply(this, arguments) || this; 12301 _this.rootElRef = createRef(); 12302 _this.state = { 12303 dayNumberId: getUniqueDomId(), 12304 }; 12305 _this.handleRootEl = function (el) { 12306 setRef(_this.rootElRef, el); 12307 setRef(_this.props.elRef, el); 12308 }; 12309 return _this; 12310 } 12311 TableCell.prototype.render = function () {
12312 var _a = this, context = _a.context, props = _a.props, state = _a.state, rootElRef = _a.rootElRef; 12313 var date = props.date, dateProfile = props.dateProfile; 12314 var navLinkAttrs = buildNavLinkAttrs(context, date, 'week'); 12315 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 } : {})), 12316 createElement("div", { className: "fc-daygrid-day-frame fc-scrollgrid-sync-inner", ref: props.innerElRef /* different from hook system! RENAME */ }, 12317 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)); })), 12318 !isDisabled && (createElement(TableCellTop, { date: date, dateProfile: dateProfile, showDayNumber: props.showDayNumber, dayNumberId: state.dayNumberId, forceDayTop: props.forceDayTop, todayRange: props.todayRange, extraHookProps: props.extraHookProps })), 12319 createElement("div", { className: "fc-daygrid-day-events", ref: props.fgContentElRef }, 12320 props.fgContent, 12321 createElement("div", { className: "fc-daygrid-day-bottom", style: { marginTop: props.moreMarginTop } }, 12322 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 }))), 12323 createElement("div", { className: "fc-daygrid-day-bg" }, props.bgContent)))); })); 12324 }; 12325 return TableCell; 12326 }(DateComponent)); 12327 12328 function computeFgSegPlacement(segs, // assumed already sorted 12329 dayMaxEvents, dayMaxEventRows, strictOrder, eventInstanceHeights, maxContentHeight, cells) { 12330 var hierarchy = new DayGridSegHierarchy(); 12331 hierarchy.allowReslicing = true; 12332 hierarchy.strictOrder = strictOrder; 12333 if (dayMaxEvents === true || dayMaxEventRows === true) { 12334 hierarchy.maxCoord = maxContentHeight; 12335 hierarchy.hiddenConsumes = true; 12336 } 12337 else if (typeof dayMaxEvents === 'number') { 12338 hierarchy.maxStackCnt = dayMaxEvents; 12339 } 12340 else if (typeof dayMaxEventRows === 'number') { 12341 hierarchy.maxStackCnt = dayMaxEventRows; 12342 hierarchy.hiddenConsumes = true; 12343 } 12344 // create segInputs only for segs with known heights 12345 var segInputs = []; 12346 var unknownHeightSegs = []; 12347 for (var i = 0; i < segs.length; i += 1) { 12348 var seg = segs[i]; 12349 var instanceId = seg.eventRange.instance.instanceId; 12350 var eventHeight = eventInstanceHeights[instanceId]; 12351 if (eventHeight != null) { 12352 segInputs.push({ 12353 index: i, 12354 thickness: eventHeight, 12355 span: { 12356 start: seg.firstCol, 12357 end: seg.lastCol + 1, 12358 }, 12359 }); 12360 } 12361 else { 12362 unknownHeightSegs.push(seg); 12363 } 12364 } 12365 var hiddenEntries = hierarchy.addSegs(segInputs); 12366 var segRects = hierarchy.toRects(); 12367 var _a = placeRects(segRects, segs, cells), singleColPlacements = _a.singleColPlacements, multiColPlacements = _a.multiColPlacements, leftoverMargins = _a.leftoverMargins; 12368 var moreCnts = []; 12369 var moreMarginTops = []; 12370 // add segs with unknown heights 12371 for (var _i = 0, unknownHeightSegs_1 = unknownHeightSegs; _i < unknownHeightSegs_1.length; _i++) { 12372 var seg = unknownHeightSegs_1[_i]; 12373 multiColPlacements[seg.firstCol].push({ 12374 seg: seg, 12375 isVisible: false, 12376 isAbsolute: true, 12377 absoluteTop: 0, 12378 marginTop: 0, 12379 });
12380 for (var col = seg.firstCol; col <= seg.lastCol; col += 1) { 12381 singleColPlacements[col].push({ 12382 seg: resliceSeg(seg, col, col + 1, cells), 12383 isVisible: false, 12384 isAbsolute: false, 12385 absoluteTop: 0, 12386 marginTop: 0, 12387 }); 12388 } 12389 } 12390 // add the hidden entries 12391 for (var col = 0; col < cells.length; col += 1) { 12392 moreCnts.push(0); 12393 } 12394 for (var _b = 0, hiddenEntries_1 = hiddenEntries; _b < hiddenEntries_1.length; _b++) { 12395 var hiddenEntry = hiddenEntries_1[_b]; 12396 var seg = segs[hiddenEntry.index]; 12397 var hiddenSpan = hiddenEntry.span; 12398 multiColPlacements[hiddenSpan.start].push({ 12399 seg: resliceSeg(seg, hiddenSpan.start, hiddenSpan.end, cells), 12400 isVisible: false, 12401 isAbsolute: true, 12402 absoluteTop: 0, 12403 marginTop: 0, 12404 }); 12405 for (var col = hiddenSpan.start; col < hiddenSpan.end; col += 1) { 12406 moreCnts[col] += 1; 12407 singleColPlacements[col].push({ 12408 seg: resliceSeg(seg, col, col + 1, cells), 12409 isVisible: false, 12410 isAbsolute: false, 12411 absoluteTop: 0, 12412 marginTop: 0, 12413 }); 12414 } 12415 } 12416 // deal with leftover margins 12417 for (var col = 0; col < cells.length; col += 1) { 12418 moreMarginTops.push(leftoverMargins[col]); 12419 } 12420 return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, moreCnts: moreCnts, moreMarginTops: moreMarginTops }; 12421 } 12422 // rects ordered by top coord, then left 12423 function placeRects(allRects, segs, cells) { 12424 var rectsByEachCol = groupRectsByEachCol(allRects, cells.length); 12425 var singleColPlacements = []; 12426 var multiColPlacements = []; 12427 var leftoverMargins = []; 12428 for (var col = 0; col < cells.length; col += 1) { 12429 var rects = rectsByEachCol[col]; 12430 // compute all static segs in singlePlacements 12431 var singlePlacements = []; 12432 var currentHeight = 0; 12433 var currentMarginTop = 0; 12434 for (var _i = 0, rects_1 = rects; _i < rects_1.length; _i++) { 12435 var rect = rects_1[_i]; 12436 var seg = segs[rect.index]; 12437 singlePlacements.push({ 12438 seg: resliceSeg(seg, col, col + 1, cells), 12439 isVisible: true, 12440 isAbsolute: false, 12441 absoluteTop: rect.levelCoord, 12442 marginTop: rect.levelCoord - currentHeight, 12443 }); 12444 currentHeight = rect.levelCoord + rect.thickness; 12445 } 12446 // compute mixed static/absolute segs in multiPlacements 12447 var multiPlacements = []; 12448 currentHeight = 0; 12449 currentMarginTop = 0; 12450 for (var _a = 0, rects_2 = rects; _a < rects_2.length; _a++) { 12451 var rect = rects_2[_a]; 12452 var seg = segs[rect.index]; 12453 var isAbsolute = rect.span.end - rect.span.start > 1; // multi-column? 12454 var isFirstCol = rect.span.start === col; 12455 currentMarginTop += rect.levelCoord - currentHeight; // amount of space since bottom of previous seg 12456 currentHeight = rect.levelCoord + rect.thickness; // height will now be bottom of current seg 12457 if (isAbsolute) { 12458 currentMarginTop += rect.thickness; 12459 if (isFirstCol) { 12460 multiPlacements.push({ 12461 seg: resliceSeg(seg, rect.span.start, rect.span.end, cells), 12462 isVisible: true, 12463 isAbsolute: true, 12464 absoluteTop: rect.levelCoord, 12465 marginTop: 0, 12466 }); 12467 } 12468 } 12469 else if (isFirstCol) { 12470 multiPlacements.push({ 12471 seg: resliceSeg(seg, rect.span.start, rect.span.end, cells), 12472 isVisible: true, 12473 isAbsolute: false, 12474 absoluteTop: rect.levelCoord, 12475 marginTop: currentMarginTop, // claim the margin 12476 }); 12477 currentMarginTop = 0; 12478 } 12479 } 12480 singleColPlacements.push(singlePlacements); 12481 multiColPlacements.push(multiPlacements); 12482 leftoverMargins.push(currentMarginTop); 12483 } 12484 return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, leftoverMargins: leftoverMargins }; 12485 } 12486 function groupRectsByEachCol(rects, colCnt) { 12487 var rectsByEachCol = []; 12488 for (var col = 0; col < colCnt; col += 1) { 12489 rectsByEachCol.push([]); 12490 } 12491 for (var _i = 0, rects_3 = rects; _i < rects_3.length; _i++) { 12492 var rect = rects_3[_i]; 12493 for (var col = rect.span.start; col < rect.span.end; col += 1) { 12494 rectsByEachCol[col].push(rect); 12495 } 12496 } 12497 return rectsByEachCol; 12498 } 12499 function resliceSeg(seg, spanStart, spanEnd, cells) { 12500 if (seg.firstCol === spanStart && seg.lastCol === spanEnd - 1) { 12501 return seg; 12502 } 12503 var eventRange = seg.eventRange; 12504 var origRange = eventRange.range; 12505 var slicedRange = intersectRanges(origRange, { 12506 start: cells[spanStart].date, 12507 end: addDays(cells[spanEnd - 1].date, 1), 12508 }); 12509 return __assign(__assign({}, seg), { firstCol: spanStart, lastCol: spanEnd - 1, eventRange: { 12510 def: eventRange.def, 12511 ui: __assign(__assign({}, eventRange.ui), { durationEditable: false }), 12512 instance: eventRange.instance, 12513 range: slicedRange, 12514 }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() }); 12515 } 12516 var DayGridSegHierarchy = /** @class */ (function (_super) { 12517 __extends(DayGridSegHierarchy, _super); 12518 function DayGridSegHierarchy() { 12519 var _this = _super !== null && _super.apply(this, arguments) || this; 12520 // config 12521 _this.hiddenConsumes = false;
12522 // allows us to keep hidden entries in the hierarchy so they take up space 12523 _this.forceHidden = {}; 12524 return _this; 12525 } 12526 DayGridSegHierarchy.prototype.addSegs = function (segInputs) { 12527 var _this = this; 12528 var hiddenSegs = _super.prototype.addSegs.call(this, segInputs); 12529 var entriesByLevel = this.entriesByLevel; 12530 var excludeHidden = function (entry) { return !_this.forceHidden[buildEntryKey(entry)]; }; 12531 // remove the forced-hidden segs 12532 for (var level = 0; level < entriesByLevel.length; level += 1) { 12533 entriesByLevel[level] = entriesByLevel[level].filter(excludeHidden); 12534 } 12535 return hiddenSegs; 12536 }; 12537 DayGridSegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) { 12538 var _a = this, entriesByLevel = _a.entriesByLevel, forceHidden = _a.forceHidden; 12539 var touchingEntry = insertion.touchingEntry, touchingLevel = insertion.touchingLevel, touchingLateral = insertion.touchingLateral; 12540 if (this.hiddenConsumes && touchingEntry) { 12541 var touchingEntryId = buildEntryKey(touchingEntry); 12542 // if not already hidden 12543 if (!forceHidden[touchingEntryId]) { 12544 if (this.allowReslicing) { 12545 var placeholderEntry = __assign(__assign({}, touchingEntry), { span: intersectSpans(touchingEntry.span, entry.span) }); 12546 var placeholderEntryId = buildEntryKey(placeholderEntry); 12547 forceHidden[placeholderEntryId] = true; 12548 entriesByLevel[touchingLevel][touchingLateral] = placeholderEntry; // replace touchingEntry with our placeholder 12549 this.splitEntry(touchingEntry, entry, hiddenEntries); // split up the touchingEntry, reinsert it 12550 } 12551 else { 12552 forceHidden[touchingEntryId] = true; 12553 hiddenEntries.push(touchingEntry); 12554 } 12555 } 12556 } 12557 return _super.prototype.handleInvalidInsertion.call(this, insertion, entry, hiddenEntries); 12558 }; 12559 return DayGridSegHierarchy; 12560 }(SegHierarchy)); 12561 12562 var TableRow = /** @class */ (function (_super) { 12563 __extends(TableRow, _super); 12564 function TableRow() { 12565 var _this = _super !== null && _super.apply(this, arguments) || this; 12566 _this.cellElRefs = new RefMap(); // the <td> 12567 _this.frameElRefs = new RefMap(); // the fc-daygrid-day-frame 12568 _this.fgElRefs = new RefMap(); // the fc-daygrid-day-events 12569 _this.segHarnessRefs = new RefMap(); // indexed by "instanceId:firstCol" 12570 _this.rootElRef = createRef(); 12571 _this.state = { 12572 framePositions: null, 12573 maxContentHeight: null, 12574 eventInstanceHeights: {}, 12575 }; 12576 return _this; 12577 } 12578 TableRow.prototype.render = function () { 12579 var _this = this; 12580 var _a = this, props = _a.props, state = _a.state, context = _a.context; 12581 var options = context.options; 12582 var colCnt = props.cells.length; 12583 var businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt); 12584 var bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt); 12585 var highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt); 12586 var mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt); 12587 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; 12588 var isForcedInvisible = // TODO: messy way to compute this 12589 (props.eventDrag && props.eventDrag.affectedInstances) || 12590 (props.eventResize && props.eventResize.affectedInstances) || 12591 {}; 12592 return (createElement("tr", { ref: this.rootElRef, role: "row" }, 12593 props.renderIntro && props.renderIntro(), 12594 props.cells.map(function (cell, col) { 12595 var normalFgNodes = _this.renderFgSegs(col, props.forPrint ? singleColPlacements[col] : multiColPlacements[col], props.todayRange, isForcedInvisible); 12596 var mirrorFgNodes = _this.renderFgSegs(col, buildMirrorPlacements(mirrorSegsByCol[col], multiColPlacements), props.todayRange, {}, Boolean(props.eventDrag), Boolean(props.eventResize), false); 12597 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 12598 createElement(Fragment, null, 12599 createElement(Fragment, null, normalFgNodes), 12600 createElement(Fragment, null, mirrorFgNodes))), bgContent: ( // Fragment scopes the keys 12601 createElement(Fragment, null, 12602 _this.renderFillSegs(highlightSegsByCol[col], 'highlight'), 12603 _this.renderFillSegs(businessHoursByCol[col], 'non-business'), 12604 _this.renderFillSegs(bgEventSegsByCol[col], 'bg-event'))) })); 12605 }))); 12606 }; 12607 TableRow.prototype.componentDidMount = function () { 12608 this.updateSizing(true); 12609 }; 12610 TableRow.prototype.componentDidUpdate = function (prevProps, prevState) { 12611 var currentProps = this.props; 12612 this.updateSizing(!isPropsEqual(prevProps, currentProps)); 12613 }; 12614 TableRow.prototype.getHighlightSegs = function () { 12615 var props = this.props; 12616 if (props.eventDrag && props.eventDrag.segs.length) { // messy check 12617 return props.eventDrag.segs; 12618 } 12619 if (props.eventResize && props.eventResize.segs.length) { // messy check 12620 return props.eventResize.segs; 12621 } 12622 return props.dateSelectionSegs; 12623 }; 12624 TableRow.prototype.getMirrorSegs = function () { 12625 var props = this.props; 12626 if (props.eventResize && props.eventResize.segs.length) { // messy check 12627 return props.eventResize.segs; 12628 } 12629 return []; 12630 }; 12631 TableRow.prototype.renderFgSegs = function (col, segPlacements, todayRange, isForcedInvisible, isDragging, isResizing, isDateSelecting) { 12632 var context = this.context; 12633 var eventSelection = this.props.eventSelection; 12634 var framePositions = this.state.framePositions; 12635 var defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1 12636 var isMirror = isDragging || isResizing || isDateSelecting; 12637 var nodes = []; 12638 if (framePositions) { 12639 for (var _i = 0, segPlacements_1 = segPlacements; _i < segPlacements_1.length; _i++) { 12640 var placement = segPlacements_1[_i]; 12641 var seg = placement.seg; 12642 var instanceId = seg.eventRange.instance.instanceId; 12643 var key = instanceId + ':' + col; 12644 var isVisible = placement.isVisible && !isForcedInvisible[instanceId];
12645 var isAbsolute = placement.isAbsolute; 12646 var left = ''; 12647 var right = ''; 12648 if (isAbsolute) { 12649 if (context.isRtl) { 12650 right = 0; 12651 left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol]; 12652 } 12653 else { 12654 left = 0; 12655 right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol]; 12656 } 12657 } 12658 /* 12659 known bug: events that are force to be list-item but span multiple days still take up space in later columns 12660 todo: in print view, for multi-day events, don't display title within non-start/end segs 12661 */ 12662 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: { 12663 visibility: isVisible ? '' : 'hidden', 12664 marginTop: isAbsolute ? '' : placement.marginTop, 12665 top: isAbsolute ? placement.absoluteTop : '', 12666 left: left, 12667 right: right, 12668 } }, 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)))))); 12669 } 12670 } 12671 return nodes; 12672 }; 12673 TableRow.prototype.renderFillSegs = function (segs, fillType) { 12674 var isRtl = this.context.isRtl; 12675 var todayRange = this.props.todayRange; 12676 var framePositions = this.state.framePositions; 12677 var nodes = []; 12678 if (framePositions) { 12679 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 12680 var seg = segs_1[_i]; 12681 var leftRightCss = isRtl ? { 12682 right: 0, 12683 left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol], 12684 } : { 12685 left: 0, 12686 right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol], 12687 }; 12688 nodes.push(createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-daygrid-bg-harness", style: leftRightCss }, fillType === 'bg-event' ? 12689 createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, todayRange))) : 12690 renderFill(fillType))); 12691 } 12692 } 12693 return createElement.apply(void 0, __spreadArray([Fragment, {}], nodes)); 12694 }; 12695 TableRow.prototype.updateSizing = function (isExternalSizingChange) { 12696 var _a = this, props = _a.props, frameElRefs = _a.frameElRefs; 12697 if (!props.forPrint && 12698 props.clientWidth !== null // positioning ready? 12699 ) { 12700 if (isExternalSizingChange) { 12701 var frameEls = props.cells.map(function (cell) { return frameElRefs.currentMap[cell.key]; }); 12702 if (frameEls.length) { 12703 var originEl = this.rootElRef.current; 12704 this.setState({ 12705 framePositions: new PositionCache(originEl, frameEls, true, // isHorizontal 12706 false), 12707 }); 12708 } 12709 } 12710 var oldInstanceHeights = this.state.eventInstanceHeights; 12711 var newInstanceHeights = this.queryEventInstanceHeights(); 12712 var limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true; 12713 this.setState({ 12714 // HACK to prevent oscillations of events being shown/hidden from max-event-rows 12715 // Essentially, once you compute an element's height, never null-out. 12716 // TODO: always display all events, as visibility:hidden? 12717 eventInstanceHeights: __assign(__assign({}, oldInstanceHeights), newInstanceHeights), 12718 maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null, 12719 }); 12720 } 12721 }; 12722 TableRow.prototype.queryEventInstanceHeights = function () { 12723 var segElMap = this.segHarnessRefs.currentMap; 12724 var eventInstanceHeights = {}; 12725 // get the max height amongst instance segs 12726 for (var key in segElMap) { 12727 var height = Math.round(segElMap[key].getBoundingClientRect().height); 12728 var instanceId = key.split(':')[0]; // deconstruct how renderFgSegs makes the key 12729 eventInstanceHeights[instanceId] = Math.max(eventInstanceHeights[instanceId] || 0, height); 12730 } 12731 return eventInstanceHeights; 12732 }; 12733 TableRow.prototype.computeMaxContentHeight = function () { 12734 var firstKey = this.props.cells[0].key; 12735 var cellEl = this.cellElRefs.currentMap[firstKey]; 12736 var fcContainerEl = this.fgElRefs.currentMap[firstKey]; 12737 return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top; 12738 }; 12739 TableRow.prototype.getCellEls = function () { 12740 var elMap = this.cellElRefs.currentMap; 12741 return this.props.cells.map(function (cell) { return elMap[cell.key]; }); 12742 }; 12743 return TableRow; 12744 }(DateComponent)); 12745 TableRow.addStateEquality({ 12746 eventInstanceHeights: isPropsEqual, 12747 }); 12748 function buildMirrorPlacements(mirrorSegs, colPlacements) { 12749 if (!mirrorSegs.length) { 12750 return []; 12751 } 12752 var topsByInstanceId = buildAbsoluteTopHash(colPlacements); // TODO: cache this at first render? 12753 return mirrorSegs.map(function (seg) { return ({ 12754 seg: seg, 12755 isVisible: true, 12756 isAbsolute: true, 12757 absoluteTop: topsByInstanceId[seg.eventRange.instance.instanceId], 12758 marginTop: 0, 12759 }); }); 12760 } 12761 function buildAbsoluteTopHash(colPlacements) { 12762 var topsByInstanceId = {}; 12763 for (var _i = 0, colPlacements_1 = colPlacements; _i < colPlacements_1.length; _i++) { 12764 var placements = colPlacements_1[_i]; 12765 for (var _a = 0, placements_1 = placements; _a < placements_1.length; _a++) { 12766 var placement = placements_1[_a]; 12767 topsByInstanceId[placement.seg.eventRange.instance.instanceId] = placement.absoluteTop; 12768 } 12769 } 12770 return topsByInstanceId; 12771 } 12772 12773 var Table = /** @class */ (function (_super) { 12774 __extends(Table, _super); 12775 function Table() { 12776 var _this = _super !== null && _super.apply(this, arguments) || this; 12777 _this.splitBusinessHourSegs = memoize(splitSegsByRow); 12778 _this.splitBgEventSegs = memoize(splitSegsByRow); 12779 _this.splitFgEventSegs = memoize(splitSegsByRow); 12780 _this.splitDateSelectionSegs = memoize(splitSegsByRow); 12781 _this.splitEventDrag = memoize(splitInteractionByRow); 12782 _this.splitEventResize = memoize(splitInteractionByRow); 12783 _this.rowRefs = new RefMap(); 12784 _this.handleRootEl = function (rootEl) { 12785 _this.rootEl = rootEl; 12786 if (rootEl) { 12787 _this.context.registerInteractiveComponent(_this, { 12788 el: rootEl, 12789 isHitComboAllowed: _this.props.isHitComboAllowed, 12790 }); 12791 } 12792 else { 12793 _this.context.unregisterInteractiveComponent(_this); 12794 } 12795 }; 12796 return _this; 12797 } 12798 Table.prototype.render = function () { 12799 var _this = this; 12800 var props = this.props; 12801 var dateProfile = props.dateProfile, dayMaxEventRows = props.dayMaxEventRows, dayMaxEvents = props.dayMaxEvents, expandRows = props.expandRows; 12802 var rowCnt = props.cells.length; 12803 var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt); 12804 var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt); 12805 var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt); 12806 var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt); 12807 var eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt); 12808 var eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt); 12809 var limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true; 12810 // if rows can't expand to fill fixed height, can't do balanced-height event limit 12811 // TODO: best place to normalize these options? 12812 if (limitViaBalanced && !expandRows) { 12813 limitViaBalanced = false;
12814 dayMaxEventRows = null; 12815 dayMaxEvents = null; 12816 } 12817 var classNames = [ 12818 'fc-daygrid-body', 12819 limitViaBalanced ? 'fc-daygrid-body-balanced' : 'fc-daygrid-body-unbalanced', 12820 expandRows ? '' : 'fc-daygrid-body-natural', // will height of one row depend on the others? 12821 ]; 12822 return (createElement("div", { className: classNames.join(' '), ref: this.handleRootEl, style: { 12823 // these props are important to give this wrapper correct dimensions for interactions 12824 // TODO: if we set it here, can we avoid giving to inner tables? 12825 width: props.clientWidth, 12826 minWidth: props.tableMinWidth, 12827 } }, 12828 createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement(Fragment, null, 12829 createElement("table", { role: "presentation", className: "fc-scrollgrid-sync-table", style: { 12830 width: props.clientWidth, 12831 minWidth: props.tableMinWidth, 12832 height: expandRows ? props.clientHeight : '', 12833 } }, 12834 props.colGroupNode, 12835 createElement("tbody", { role: "presentation" }, props.cells.map(function (cells, row) { return (createElement(TableRow, { ref: _this.rowRefs.createRef(row), key: cells.length 12836 ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */ 12837 : row // in case there are no cells (like when resource view is loading) 12838 , 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 })); }))))); }))); 12839 }; 12840 // Hit System 12841 // ---------------------------------------------------------------------------------------------------- 12842 Table.prototype.prepareHits = function () { 12843 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 12844 false, true); 12845 this.colPositions = new PositionCache(this.rootEl, this.rowRefs.currentMap[0].getCellEls(), // cell els in first row 12846 true, // horizontal 12847 false); 12848 }; 12849 Table.prototype.queryHit = function (positionLeft, positionTop) { 12850 var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions; 12851 var col = colPositions.leftToIndex(positionLeft); 12852 var row = rowPositions.topToIndex(positionTop); 12853 if (row != null && col != null) { 12854 var cell = this.props.cells[row][col]; 12855 return { 12856 dateProfile: this.props.dateProfile, 12857 dateSpan: __assign({ range: this.getCellRange(row, col), allDay: true }, cell.extraDateSpan), 12858 dayEl: this.getCellEl(row, col), 12859 rect: { 12860 left: colPositions.lefts[col], 12861 right: colPositions.rights[col], 12862 top: rowPositions.tops[row], 12863 bottom: rowPositions.bottoms[row], 12864 }, 12865 layer: 0, 12866 }; 12867 } 12868 return null; 12869 }; 12870 Table.prototype.getCellEl = function (row, col) { 12871 return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal 12872 }; 12873 Table.prototype.getCellRange = function (row, col) { 12874 var start = this.props.cells[row][col].date; 12875 var end = addDays(start, 1); 12876 return { start: start, end: end }; 12877 }; 12878 return Table; 12879 }(DateComponent)); 12880 function isSegAllDay(seg) { 12881 return seg.eventRange.def.allDay; 12882 } 12883 12884 var DayTableSlicer = /** @class */ (function (_super) { 12885 __extends(DayTableSlicer, _super); 12886 function DayTableSlicer() { 12887 var _this = _super !== null && _super.apply(this, arguments) || this; 12888 _this.forceDayIfListItem = true; 12889 return _this; 12890 } 12891 DayTableSlicer.prototype.sliceRange = function (dateRange, dayTableModel) { 12892 return dayTableModel.sliceRange(dateRange); 12893 }; 12894 return DayTableSlicer; 12895 }(Slicer)); 12896 12897 var DayTable = /** @class */ (function (_super) { 12898 __extends(DayTable, _super); 12899 function DayTable() { 12900 var _this = _super !== null && _super.apply(this, arguments) || this; 12901 _this.slicer = new DayTableSlicer(); 12902 _this.tableRef = createRef(); 12903 return _this; 12904 } 12905 DayTable.prototype.render = function () { 12906 var _a = this, props = _a.props, context = _a.context; 12907 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 }))); 12908 }; 12909 return DayTable; 12910 }(DateComponent)); 12911 12912 var DayTableView = /** @class */ (function (_super) { 12913 __extends(DayTableView, _super); 12914 function DayTableView() { 12915 var _this = _super !== null && _super.apply(this, arguments) || this; 12916 _this.buildDayTableModel = memoize(buildDayTableModel); 12917 _this.headerRef = createRef(); 12918 _this.tableRef = createRef(); 12919 return _this; 12920 } 12921 DayTableView.prototype.render = function () { 12922 var _this = this; 12923 var _a = this.context, options = _a.options, dateProfileGenerator = _a.dateProfileGenerator; 12924 var props = this.props; 12925 var dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator); 12926 var headerContent = options.dayHeaders && (createElement(DayHeader, { ref: this.headerRef, dateProfile: props.dateProfile, dates: dayTableModel.headerDates, datesRepDistinctDays: dayTableModel.rowCnt === 1 })); 12927 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 })); }; 12928 return options.dayMinWidth 12929 ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth) 12930 : this.renderSimpleLayout(headerContent, bodyContent); 12931 }; 12932 return DayTableView; 12933 }(TableView)); 12934 function buildDayTableModel(dateProfile, dateProfileGenerator) {
12935 var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator); 12936 return new DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit)); 12937 } 12938 12939 var TableDateProfileGenerator = /** @class */ (function (_super) { 12940 __extends(TableDateProfileGenerator, _super); 12941 function TableDateProfileGenerator() { 12942 return _super !== null && _super.apply(this, arguments) || this; 12943 } 12944 // Computes the date range that will be rendered. 12945 TableDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) { 12946 var dateEnv = this.props.dateEnv; 12947 var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay); 12948 var start = renderRange.start; 12949 var end = renderRange.end; 12950 var endOfWeek; 12951 // year and month views should be aligned with weeks. this is already done for week 12952 if (/^(year|month)$/.test(currentRangeUnit)) { 12953 start = dateEnv.startOfWeek(start); 12954 // make end-of-week if not already 12955 endOfWeek = dateEnv.startOfWeek(end); 12956 if (endOfWeek.valueOf() !== end.valueOf()) { 12957 end = addWeeks(endOfWeek, 1); 12958 } 12959 } 12960 // ensure 6 weeks 12961 if (this.props.monthMode && 12962 this.props.fixedWeekCount) { 12963 var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays 12964 diffWeeks(start, end)); 12965 end = addWeeks(end, 6 - rowCnt); 12966 } 12967 return { start: start, end: end }; 12968 }; 12969 return TableDateProfileGenerator; 12970 }(DateProfileGenerator)); 12971 12972 var dayGridPlugin = createPlugin({ 12973 initialView: 'dayGridMonth', 12974 views: { 12975 dayGrid: { 12976 component: DayTableView, 12977 dateProfileGeneratorClass: TableDateProfileGenerator, 12978 }, 12979 dayGridDay: { 12980 type: 'dayGrid', 12981 duration: { days: 1 }, 12982 }, 12983 dayGridWeek: { 12984 type: 'dayGrid', 12985 duration: { weeks: 1 }, 12986 }, 12987 dayGridMonth: { 12988 type: 'dayGrid', 12989 duration: { months: 1 }, 12990 monthMode: true, 12991 fixedWeekCount: true, 12992 }, 12993 }, 12994 }); 12995 12996 var AllDaySplitter = /** @class */ (function (_super) { 12997 __extends(AllDaySplitter, _super); 12998 function AllDaySplitter() { 12999 return _super !== null && _super.apply(this, arguments) || this; 13000 } 13001 AllDaySplitter.prototype.getKeyInfo = function () { 13002 return { 13003 allDay: {}, 13004 timed: {}, 13005 }; 13006 }; 13007 AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) { 13008 if (dateSpan.allDay) { 13009 return ['allDay']; 13010 } 13011 return ['timed']; 13012 }; 13013 AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) { 13014 if (!eventDef.allDay) { 13015 return ['timed']; 13016 } 13017 if (hasBgRendering(eventDef)) { 13018 return ['timed', 'allDay']; 13019 } 13020 return ['allDay']; 13021 }; 13022 return AllDaySplitter; 13023 }(Splitter)); 13024 13025 var DEFAULT_SLAT_LABEL_FORMAT = createFormatter({ 13026 hour: 'numeric', 13027 minute: '2-digit', 13028 omitZeroMinute: true, 13029 meridiem: 'short', 13030 }); 13031 function TimeColsAxisCell(props) { 13032 var classNames = [ 13033 'fc-timegrid-slot', 13034 'fc-timegrid-slot-label', 13035 props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor', 13036 ]; 13037 return (createElement(ViewContextType.Consumer, null, function (context) { 13038 if (!props.isLabeled) { 13039 return (createElement("td", { className: classNames.join(' '), "data-time": props.isoTimeStr })); 13040 } 13041 var dateEnv = context.dateEnv, options = context.options, viewApi = context.viewApi; 13042 var labelFormat = // TODO: fully pre-parse 13043 options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT : 13044 Array.isArray(options.slotLabelFormat) ? createFormatter(options.slotLabelFormat[0]) : 13045 createFormatter(options.slotLabelFormat); 13046 var hookProps = { 13047 level: 0, 13048 time: props.time, 13049 date: dateEnv.toDate(props.date), 13050 view: viewApi, 13051 text: dateEnv.format(props.date, labelFormat), 13052 }; 13053 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
13053oncat(customClassNames).join(' '), "data-time": props.isoTimeStr }, 13054 createElement("div", { className: "fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame" }, 13055 createElement("div", { className: "fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion", ref: innerElRef }, innerContent)))); })); 13056 })); 13057 } 13058 function renderInnerContent$1(props) { 13059 return props.text; 13060 } 13061 13062 var TimeBodyAxis = /** @class */ (function (_super) { 13063 __extends(TimeBodyAxis, _super); 13064 function TimeBodyAxis() { 13065 return _super !== null && _super.apply(this, arguments) || this; 13066 } 13067 TimeBodyAxis.prototype.render = function () { 13068 return this.props.slatMetas.map(function (slatMeta) { return (createElement("tr", { key: slatMeta.key }, 13069 createElement(TimeColsAxisCell, __assign({}, slatMeta)))); }); 13070 }; 13071 return TimeBodyAxis; 13072 }(BaseComponent)); 13073 13074 var DEFAULT_WEEK_NUM_FORMAT = createFormatter({ week: 'short' }); 13075 var AUTO_ALL_DAY_MAX_EVENT_ROWS = 5; 13076 var TimeColsView = /** @class */ (function (_super) { 13077 __extends(TimeColsView, _super); 13078 function TimeColsView() { 13079 var _this = _super !== null && _super.apply(this, arguments) || this; 13080 _this.allDaySplitter = new AllDaySplitter(); // for use by subclasses 13081 _this.headerElRef = createRef(); 13082 _this.rootElRef = createRef(); 13083 _this.scrollerElRef = createRef(); 13084 _this.state = { 13085 slatCoords: null, 13086 }; 13087 _this.handleScrollTopRequest = function (scrollTop) { 13088 var scrollerEl = _this.scrollerElRef.current; 13089 if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer 13090 scrollerEl.scrollTop = scrollTop; 13091 } 13092 }; 13093 /* Header Render Methods 13094 ------------------------------------------------------------------------------------------------------------------*/ 13095 _this.renderHeadAxis = function (rowKey, frameHeight) { 13096 if (frameHeight === void 0) { frameHeight = ''; } 13097 var options = _this.context.options; 13098 var dateProfile = _this.props.dateProfile; 13099 var range = dateProfile.renderRange; 13100 var dayCnt = diffDays(range.start, range.end); 13101 var navLinkAttrs = (dayCnt === 1) // only do in day views (to avoid doing in week views that dont need it) 13102 ? buildNavLinkAttrs(_this.context, range.start, 'week') 13103 : {}; 13104 if (options.weekNumbers && rowKey === 'day') { 13105 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: [ 13106 'fc-timegrid-axis', 13107 'fc-scrollgrid-shrink', 13108 ].concat(classNames).join(' ') }, 13109 createElement("div", { className: "fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid", style: { height: frameHeight } }, 13110 createElement("a", __assign({ ref: innerElRef, className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner" }, navLinkAttrs), innerContent)))); })); 13111 } 13112 return (createElement("th", { "aria-hidden": true, className: "fc-timegrid-axis" }, 13113 createElement("div", { className: "fc-timegrid-axis-frame", style: { height: frameHeight } }))); 13114 }; 13115 /* Table Component Render Methods 13116 ------------------------------------------------------------------------------------------------------------------*/ 13117 // only a one-way height sync. we don't send the axis inner-content height to the DayGrid, 13118 // but DayGrid still needs to have classNames on inner elements in order to measure. 13119 _this.renderTableRowAxis = function (rowHeight) { 13120 var _a = _this.context, options = _a.options, viewApi = _a.viewApi; 13121 var hookProps = { 13122 text: options.allDayText, 13123 view: viewApi, 13124 }; 13125 return ( 13126 // TODO: make reusable hook. used in list view too 13127 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: [ 13128 'fc-timegrid-axis', 13129 'fc-scrollgrid-shrink', 13130 ].concat(classNames).join(' ') }, 13131 createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame' + (rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : ''), style: { height: rowHeight } }, 13132 createElement("span", { className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner", ref: innerElRef }, innerContent)))); })); 13133 }; 13134 _this.handleSlatCoords = function (slatCoords) {
13135 _this.setState({ slatCoords: slatCoords }); 13136 }; 13137 return _this; 13138 } 13139 // rendering 13140 // ---------------------------------------------------------------------------------------------------- 13141 TimeColsView.prototype.renderSimpleLayout = function (headerRowContent, allDayContent, timeContent) { 13142 var _a = this, context = _a.context, props = _a.props; 13143 var sections = []; 13144 var stickyHeaderDates = getStickyHeaderDates(context.options); 13145 if (headerRowContent) { 13146 sections.push({ 13147 type: 'header', 13148 key: 'header', 13149 isSticky: stickyHeaderDates, 13150 chunk: { 13151 elRef: this.headerElRef, 13152 tableClassName: 'fc-col-header', 13153 rowContent: headerRowContent, 13154 }, 13155 }); 13156 } 13157 if (allDayContent) { 13158 sections.push({ 13159 type: 'body', 13160 key: 'all-day', 13161 chunk: { content: allDayContent }, 13162 }); 13163 sections.push({ 13164 type: 'body', 13165 key: 'all-day-divider', 13166 outerContent: ( // TODO: rename to cellContent so don't need to define <tr>? 13167 createElement("tr", { role: "presentation", className: "fc-scrollgrid-section" }, 13168 createElement("td", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))), 13169 }); 13170 } 13171 sections.push({ 13172 type: 'body', 13173 key: 'body', 13174 liquid: true, 13175 expandRows: Boolean(context.options.expandRows), 13176 chunk: { 13177 scrollerElRef: this.scrollerElRef, 13178 content: timeContent, 13179 }, 13180 }); 13181 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef }, 13182 createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [{ width: 'shrink' }], sections: sections }))); })); 13183 }; 13184 TimeColsView.prototype.renderHScrollLayout = function (headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) { 13185 var _this = this; 13186 var ScrollGrid = this.context.pluginHooks.scrollGridImpl; 13187 if (!ScrollGrid) { 13188 throw new Error('No ScrollGrid implementation'); 13189 } 13190 var _a = this, context = _a.context, props = _a.props; 13191 var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options); 13192 var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options); 13193 var sections = []; 13194 if (headerRowContent) { 13195 sections.push({ 13196 type: 'header', 13197 key: 'header', 13198 isSticky: stickyHeaderDates, 13199 syncRowHeights: true, 13200 chunks: [ 13201 { 13202 key: 'axis', 13203 rowContent: function (arg) { return (createElement("tr", { role: "presentation" }, _this.renderHeadAxis('day', arg.rowSyncHeights[0]))); }, 13204 }, 13205 { 13206 key: 'cols', 13207 elRef: this.headerElRef, 13208 tableClassName: 'fc-col-header', 13209 rowContent: headerRowContent, 13210 }, 13211 ], 13212 }); 13213 } 13214 if (allDayContent) { 13215 sections.push({ 13216 type: 'body', 13217 key: 'all-day', 13218 syncRowHeights: true, 13219 chunks: [ 13220 { 13221 key: 'axis', 13222 rowContent: function (contentArg) { return (createElement("tr", { role: "presentation" }, _this.renderTableRowAxis(contentArg.rowSyncHeights[0]))); }, 13223 }, 13224 { 13225 key: 'cols', 13226 content: allDayContent, 13227 }, 13228 ], 13229 }); 13230 sections.push({ 13231 key: 'all-day-divider', 13232 type: 'body', 13233 outerContent: ( // TODO: rename to cellContent so don't need to define <tr>? 13234 createElement("tr", { role: "presentation", className: "fc-scrollgrid-section" }, 13235 createElement("td", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))), 13236 }); 13237 } 13238 var isNowIndicator = context.options.nowIndicator; 13239 sections.push({ 13240 type: 'body', 13241 key: 'body', 13242 liquid: true, 13243 expandRows: Boolean(context.options.expandRows), 13244 chunks: [ 13245 { 13246 key: 'axis', 13247 content: function (arg) { return ( 13248 // TODO: make this now-indicator arrow more DRY with TimeColsContent 13249 createElement("div", { className: "fc-timegrid-axis-chunk" }, 13250 createElement("table", { "aria-hidden": true, style: { height: arg.expandRows ? arg.clientHeight : '' } }, 13251 arg.tableColGroupNode, 13252 createElement("tbody", null, 13253 createElement(TimeBodyAxis, { slatMetas: slatMetas }))), 13254 createElement("div", { className: "fc-timegrid-now-indicator-container" }, 13255 createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, function (nowDate) { 13256 var nowIndicatorTop = isNowIndicator && 13257 slatCoords && 13258 slatCoords.safeComputeTop(nowDate); // might return void 13259 if (typeof nowIndicatorTop === 'number') { 13260 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)); })); 13261 } 13262 return null; 13263 })))); }, 13264 }, 13265 { 13266 key: 'cols', 13267 scrollerElRef: this.scrollerElRef, 13268 content: timeContent, 13269 }, 13270 ], 13271 }); 13272 if (stickyFooterScrollbar) { 13273 sections.push({ 13274 key: 'footer', 13275 type: 'footer', 13276 isSticky: true, 13277 chunks: [ 13278 { 13279 key: 'axis', 13280 content: renderScrollShim, 13281 }, 13282 { 13283 key: 'cols', 13284 content: renderScrollShim, 13285 }, 13286 ], 13287 }); 13288 } 13289 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].
13289concat(classNames).join(' '), ref: rootElRef }, 13290 createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: false, colGroups: [ 13291 { width: 'shrink', cols: [{ width: 'shrink' }] }, 13292 { cols: [{ span: colCnt, minWidth: dayMinWidth }] }, 13293 ], sections: sections }))); })); 13294 }; 13295 /* Dimensions 13296 ------------------------------------------------------------------------------------------------------------------*/ 13297 TimeColsView.prototype.getAllDayMaxEventProps = function () { 13298 var _a = this.context.options, dayMaxEvents = _a.dayMaxEvents, dayMaxEventRows = _a.dayMaxEventRows; 13299 if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto? 13300 dayMaxEvents = undefined; 13301 dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number 13302 } 13303 return { dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows }; 13304 }; 13305 return TimeColsView; 13306 }(DateComponent)); 13307 function renderAllDayInner$1(hookProps) { 13308 return hookProps.text; 13309 } 13310 13311 var TimeColsSlatsCoords = /** @class */ (function () { 13312 function TimeColsSlatsCoords(positions, dateProfile, slotDuration) { 13313 this.positions = positions; 13314 this.dateProfile = dateProfile; 13315 this.slotDuration = slotDuration; 13316 } 13317 TimeColsSlatsCoords.prototype.safeComputeTop = function (date) { 13318 var dateProfile = this.dateProfile; 13319 if (rangeContainsMarker(dateProfile.currentRange, date)) { 13320 var startOfDayDate = startOfDay(date); 13321 var timeMs = date.valueOf() - startOfDayDate.valueOf(); 13322 if (timeMs >= asRoughMs(dateProfile.slotMinTime) && 13323 timeMs < asRoughMs(dateProfile.slotMaxTime)) { 13324 return this.computeTimeTop(createDuration(timeMs)); 13325 } 13326 } 13327 return null; 13328 }; 13329 // Computes the top coordinate, relative to the bounds of the grid, of the given date. 13330 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. 13331 TimeColsSlatsCoords.prototype.computeDateTop = function (when, startOfDayDate) { 13332 if (!startOfDayDate) { 13333 startOfDayDate = startOfDay(when); 13334 } 13335 return this.computeTimeTop(createDuration(when.valueOf() - startOfDayDate.valueOf())); 13336 }; 13337 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). 13338 // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform. 13339 // Eventually allow computation with arbirary slat dates. 13340 TimeColsSlatsCoords.prototype.computeTimeTop = function (duration) { 13341 var _a = this, positions = _a.positions, dateProfile = _a.dateProfile; 13342 var len = positions.els.length; 13343 // floating-point value of # of slots covered 13344 var slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / asRoughMs(this.slotDuration); 13345 var slatIndex; 13346 var slatRemainder; 13347 // compute a floating-point number for how many slats should be progressed through. 13348 // from 0 to number of slats (inclusive) 13349 // constrained because slotMinTime/slotMaxTime might be customized. 13350 slatCoverage = Math.max(0, slatCoverage); 13351 slatCoverage = Math.min(len, slatCoverage); 13352 // an integer index of the furthest whole slat 13353 // from 0 to number slats (*exclusive*, so len-1) 13354 slatIndex = Math.floor(slatCoverage); 13355 slatIndex = Math.min(slatIndex, len - 1); 13356 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition. 13357 // could be 1.0 if slatCoverage is covering *all* the slots 13358 slatRemainder = slatCoverage - slatIndex; 13359 return positions.tops[slatIndex] + 13360 positions.getHeight(slatIndex) * slatRemainder; 13361 }; 13362 return TimeColsSlatsCoords; 13363 }()); 13364 13365 var TimeColsSlatsBody = /** @class */ (function (_super) { 13366 __extends(TimeColsSlatsBody, _super); 13367 function TimeColsSlatsBody() { 13368 return _super !== null && _super.apply(this, arguments) || this; 13369 } 13370 TimeColsSlatsBody.prototype.render = function () { 13371 var _a = this, props = _a.props, context = _a.context; 13372 var options = context.options; 13373 var slatElRefs = props.slatElRefs; 13374 return (createElement("tbody", null, props.slatMetas.map(function (slatMeta, i) { 13375 var hookProps = { 13376 time: slatMeta.time, 13377 date: context.dateEnv.toDate(slatMeta.date), 13378 view: context.viewApi, 13379 }; 13380 var classNames = [ 13381 'fc-timegrid-slot', 13382 'fc-timegrid-slot-lane', 13383 slatMeta.isLabeled ? '' : 'fc-timegrid-slot-minor', 13384 ]; 13385 return (createElement("tr", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) }, 13386 props.axis && (createElement(TimeColsAxisCell, __assign({}, slatMeta))), 13387 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
13387oncat(customClassNames).join(' '), "data-time": slatMeta.isoTimeStr }, innerContent)); }))); 13388 }))); 13389 }; 13390 return TimeColsSlatsBody; 13391 }(BaseComponent)); 13392 13393 /* 13394 for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL. 13395 */ 13396 var TimeColsSlats = /** @class */ (function (_super) { 13397 __extends(TimeColsSlats, _super); 13398 function TimeColsSlats() { 13399 var _this = _super !== null && _super.apply(this, arguments) || this; 13400 _this.rootElRef = createRef(); 13401 _this.slatElRefs = new RefMap(); 13402 return _this; 13403 } 13404 TimeColsSlats.prototype.render = function () { 13405 var _a = this, props = _a.props, context = _a.context; 13406 return (createElement("div", { ref: this.rootElRef, className: "fc-timegrid-slots" }, 13407 createElement("table", { "aria-hidden": true, className: context.theme.getClass('table'), style: { 13408 minWidth: props.tableMinWidth, 13409 width: props.clientWidth, 13410 height: props.minHeight, 13411 } }, 13412 props.tableColGroupNode /* relies on there only being a single <col> for the axis */, 13413 createElement(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas })))); 13414 }; 13415 TimeColsSlats.prototype.componentDidMount = function () { 13416 this.updateSizing(); 13417 }; 13418 TimeColsSlats.prototype.componentDidUpdate = function () { 13419 this.updateSizing(); 13420 }; 13421 TimeColsSlats.prototype.componentWillUnmount = function () { 13422 if (this.props.onCoords) { 13423 this.props.onCoords(null); 13424 } 13425 }; 13426 TimeColsSlats.prototype.updateSizing = function () { 13427 var _a = this, context = _a.context, props = _a.props; 13428 if (props.onCoords && 13429 props.clientWidth !== null // means sizing has stabilized 13430 ) { 13431 var rootEl = this.rootElRef.current; 13432 if (rootEl.offsetHeight) { // not hidden by css 13433 props.onCoords(new TimeColsSlatsCoords(new PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration)); 13434 } 13435 } 13436 }; 13437 return TimeColsSlats; 13438 }(BaseComponent)); 13439 function collectSlatEls(elMap, slatMetas) { 13440 return slatMetas.map(function (slatMeta) { return elMap[slatMeta.key]; }); 13441 } 13442 13443 function splitSegsByCol(segs, colCnt) { 13444 var segsByCol = []; 13445 var i; 13446 for (i = 0; i < colCnt; i += 1) { 13447 segsByCol.push([]); 13448 } 13449 if (segs) { 13450 for (i = 0; i < segs.length; i += 1) { 13451 segsByCol[segs[i].col].push(segs[i]); 13452 } 13453 } 13454 return segsByCol; 13455 } 13456 function splitInteractionByCol(ui, colCnt) { 13457 var byRow = []; 13458 if (!ui) { 13459 for (var i = 0; i < colCnt; i += 1) { 13460 byRow[i] = null; 13461 } 13462 } 13463 else { 13464 for (var i = 0; i < colCnt; i += 1) { 13465 byRow[i] = { 13466 affectedInstances: ui.affectedInstances, 13467 isEvent: ui.isEvent, 13468 segs: [], 13469 }; 13470 } 13471 for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) { 13472 var seg = _a[_i]; 13473 byRow[seg.col].segs.push(seg); 13474 } 13475 } 13476 return byRow; 13477 } 13478 13479 var TimeColMoreLink = /** @class */ (function (_super) { 13480 __extends(TimeColMoreLink, _super); 13481 function TimeColMoreLink() { 13482 var _this = _super !== null && _super.apply(this, arguments) || this; 13483 _this.rootElRef = createRef(); 13484 return _this; 13485 } 13486 TimeColMoreLink.prototype.render = function () { 13487 var _this = this; 13488 var props = this.props; 13489 return (createElement(MoreLinkRoot, { allDayDate: null, moreCnt: props.hiddenSegs.length, allSegs: props.hiddenSegs, hiddenSegs: props.hiddenSegs, al
13489ignmentElRef: 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) { 13490 setRef(rootElRef, el); 13491 setRef(_this.rootElRef, el); 13492 }, 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 }, 13493 createElement("div", { ref: innerElRef, className: "fc-timegrid-more-link-inner fc-sticky" }, innerContent))); })); 13494 }; 13495 return TimeColMoreLink; 13496 }(BaseComponent)); 13497 function renderMoreLinkInner(props) { 13498 return props.shortText; 13499 } 13500 13501 // segInputs assumed sorted 13502 function buildPositioning(segInputs, strictOrder, maxStackCnt) { 13503 var hierarchy = new SegHierarchy(); 13504 if (strictOrder != null) { 13505 hierarchy.strictOrder = strictOrder; 13506 } 13507 if (maxStackCnt != null) { 13508 hierarchy.maxStackCnt = maxStackCnt; 13509 } 13510 var hiddenEntries = hierarchy.addSegs(segInputs); 13511 var hiddenGroups = groupIntersectingEntries(hiddenEntries); 13512 var web = buildWeb(hierarchy); 13513 web = stretchWeb(web, 1); // all levelCoords/thickness will have 0.0-1.0 13514 var segRects = webToRects(web); 13515 return { segRects: segRects, hiddenGroups: hiddenGroups }; 13516 } 13517 function buildWeb(hierarchy) { 13518 var entriesByLevel = hierarchy.entriesByLevel; 13519 var buildNode = cacheable(function (level, lateral) { return level + ':' + lateral; }, function (level, lateral) { 13520 var siblingRange = findNextLevelSegs(hierarchy, level, lateral); 13521 var nextLevelRes = buildNodes(siblingRange, buildNode); 13522 var entry = entriesByLevel[level][lateral]; 13523 return [ 13524 __assign(__assign({}, entry), { nextLevelNodes: nextLevelRes[0] }), 13525 entry.thickness + nextLevelRes[1], // the pressure builds 13526 ]; 13527 }); 13528 return buildNodes(entriesByLevel.length 13529 ? { level: 0, lateralStart: 0, lateralEnd: entriesByLevel[0].length } 13530 : null, buildNode)[0]; 13531 } 13532 function buildNodes(siblingRange, buildNode) { 13533 if (!siblingRange) { 13534 return [[], 0]; 13535 } 13536 var level = siblingRange.level, lateralStart = siblingRange.lateralStart, lateralEnd = siblingRange.lateralEnd; 13537 var lateral = lateralStart; 13538 var pairs = []; 13539 while (lateral < lateralEnd) { 13540 pairs.push(buildNode(level, lateral)); 13541 lateral += 1; 13542 } 13543 pairs.sort(cmpDescPressures); 13544 return [ 13545 pairs.map(extractNode), 13546 pairs[0][1], // first item's pressure 13547 ]; 13548 } 13549 function cmpDescPressures(a, b) { 13550 return b[1] - a[1]; 13551 } 13552 function extractNode(a) { 13553 return a[0]; 13554 } 13555 function findNextLevelSegs(hierarchy, subjectLevel, subjectLateral) { 13556 var levelCoords = hierarchy.levelCoords, entriesByLevel = hierarchy.entriesByLevel; 13557 var subjectEntry = entriesByLevel[subjectLevel][subjectLateral]; 13558 var afterSubject = levelCoords[subjectLevel] + subjectEntry.thickness; 13559 var levelCnt = levelCoords.length; 13560 var level = subjectLevel; 13561 // skip past levels that are too high up 13562 for (; level < levelCnt && levelCoords[level] < afterSubject; level += 1) 13563 ; // do nothing 13564 for (; level < levelCnt; level += 1) { 13565 var entries = entriesByLevel[level]; 13566 var entry = void 0; 13567 var searchIndex = binarySearch(entries, subjectEntry.span.start, getEntrySpanEnd); 13568 var lateralStart = searchIndex[0] + searchIndex[1]; // if exact match (which doesn't collide), go to next one 13569 var lateralEnd = lateralStart; 13570 while ( // loop through entries that horizontally intersect 13571 (entry = entries[lateralEnd]) && // but not past the whole seg list 13572 entry.span.start < subjectEntry.span.end) { 13573 lateralEnd += 1; 13574 } 13575 if (lateralStart < lateralEnd) { 13576 return { level: level, lateralStart: lateralStart, lateralEnd: lateralEnd }; 13577 } 13578 } 13579 return null; 13580 } 13581 function stretchWeb(topLevelNodes, totalThickness) { 13582 var stretchNode = cacheable(function (node, startCoord, prevThickness) { return buildEntryKey(node); }, function (node, startCoord, prevThickness) { 13583 var nextLevelNodes = node.nextLevelNodes, thickness = node.thickness; 13584 var allThickness = thickness + prevThickness; 13585 var thicknessFraction = thickness / allThickness; 13586 var endCoord; 13587 var newChildren = []; 13588 if (!nextLevelNodes.length) { 13589 endCoord = totalThickness; 13590 } 13591 else { 13592 for (var _i = 0, nextLevelNodes_1 = nextLevelNodes; _i < nextLevelNodes_1.length; _i++) { 13593 var childNode = nextLevelNodes_1[_i]; 13594 if (endCoord === undefined) { 13595 var res = stretchNode(childNode, startCoord, allThickness); 13596 endCoord = res[0]; 13597 newChildren.push(res[1]); 13598 } 13599 else { 13600 var res = stretchNode(childNode, endCoord, 0); 13601 newChildren.push(res[1]); 13602 } 13603 } 13604 } 13605 var newThickness = (endCoord - startCoord) * thicknessFraction; 13606 return [endCoord - newThickness, __assign(__assign({}, node), { thickness: newThickness, nextLevelNodes: newChildren })]; 13607 }); 13608 return topLevelNodes.map(function (node) { return stretchNode(node,
136080, 0)[1]; }); 13609 } 13610 // not sorted in any particular order 13611 function webToRects(topLevelNodes) { 13612 var rects = []; 13613 var processNode = cacheable(function (node, levelCoord, stackDepth) { return buildEntryKey(node); }, function (node, levelCoord, stackDepth) { 13614 var rect = __assign(__assign({}, node), { levelCoord: levelCoord, 13615 stackDepth: stackDepth, stackForward: 0 }); 13616 rects.push(rect); 13617 return (rect.stackForward = processNodes(node.nextLevelNodes, levelCoord + node.thickness, stackDepth + 1) + 1); 13618 }); 13619 function processNodes(nodes, levelCoord, stackDepth) { 13620 var stackForward = 0; 13621 for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) { 13622 var node = nodes_1[_i]; 13623 stackForward = Math.max(processNode(node, levelCoord, stackDepth), stackForward); 13624 } 13625 return stackForward; 13626 } 13627 processNodes(topLevelNodes, 0, 0); 13628 return rects; // TODO: sort rects by levelCoord to be consistent with toRects? 13629 } 13630 // TODO: move to general util 13631 function cacheable(keyFunc, workFunc) { 13632 var cache = {}; 13633 return function () { 13634 var args = []; 13635 for (var _i = 0; _i < arguments.length; _i++) { 13636 args[_i] = arguments[_i]; 13637 } 13638 var key = keyFunc.apply(void 0, args); 13639 return (key in cache) 13640 ? cache[key] 13641 : (cache[key] = workFunc.apply(void 0, args)); 13642 }; 13643 } 13644 13645 function computeSegVCoords(segs, colDate, slatCoords, eventMinHeight) { 13646 if (slatCoords === void 0) { slatCoords = null; } 13647 if (eventMinHeight === void 0) { eventMinHeight = 0; } 13648 var vcoords = []; 13649 if (slatCoords) { 13650 for (var i = 0; i < segs.length; i += 1) { 13651 var seg = segs[i]; 13652 var spanStart = slatCoords.computeDateTop(seg.start, colDate); 13653 var spanEnd = Math.max(spanStart + (eventMinHeight || 0), // :( 13654 slatCoords.computeDateTop(seg.end, colDate)); 13655 vcoords.push({ 13656 start: Math.round(spanStart), 13657 end: Math.round(spanEnd), // 13658 }); 13659 } 13660 } 13661 return vcoords; 13662 } 13663 function computeFgSegPlacements(segs, segVCoords, // might not have for every seg 13664 eventOrderStrict, eventMaxStack) { 13665 var segInputs = []; 13666 var dumbSegs = []; // segs without coords 13667 for (var i = 0; i < segs.length; i += 1) { 13668 var vcoords = segVCoords[i]; 13669 if (vcoords) { 13670 segInputs.push({ 13671 index: i, 13672 thickness: 1, 13673 span: vcoords, 13674 }); 13675 } 13676 else { 13677 dumbSegs.push(segs[i]); 13678 } 13679 } 13680 var _a = buildPositioning(segInputs, eventOrderStrict, eventMaxStack), segRects = _a.segRects, hiddenGroups = _a.hiddenGroups; 13681 var segPlacements = []; 13682 for (var _i = 0, segRects_1 = segRects; _i < segRects_1.length; _i++) { 13683 var segRect = segRects_1[_i]; 13684 segPlacements.push({ 13685 seg: segs[segRect.index], 13686 rect: segRect, 13687 }); 13688 } 13689 for (var _b = 0, dumbSegs_1 = dumbSegs; _b < dumbSegs_1.length; _b++) { 13690 var dumbSeg = dumbSegs_1[_b]; 13691 segPlacements.push({ seg: dumbSeg, rect: null }); 13692 } 13693 return { segPlacements: segPlacements, hiddenGroups: hiddenGroups }; 13694 } 13695 13696 var DEFAULT_TIME_FORMAT$1 = createFormatter({ 13697 hour: 'numeric', 13698 minute: '2-digit', 13699 meridiem: false, 13700 }); 13701 var TimeColEvent = /** @class */ (function (_super) { 13702 __extends(TimeColEvent, _super); 13703 function TimeColEvent() { 13704 return _super !== null && _super.apply(this, arguments) || this; 13705 } 13706 TimeColEvent.prototype.render = function () { 13707 var classNames = [ 13708 'fc-timegrid-event', 13709 'fc-v-event', 13710 ]; 13711 if (this.props.isShort) { 13712 classNames.push('fc-timegrid-event-short'); 13713 } 13714 return (createElement(StandardEvent, __assign({}, this.props, { defaultTimeFormat: DEFAULT_TIME_FORMAT$1, extraClassNames: classNames }))); 13715 }; 13716 return TimeColEvent; 13717 }(BaseComponent)); 13718 13719 var TimeColMisc = /** @class */ (function (_super) { 13720 __extends(TimeColMisc, _super); 13721 function TimeColMisc() { 13722 return _super !== null && _super.apply(this, arguments) || this; 13723 } 13724 TimeColMisc.prototype.render = function () { 13725 var props = this.props; 13726 return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (innerElRef, innerContent) { return (innerContent && 13727 createElement("div", { className: "fc-timegrid-col-misc", ref: innerElRef }, innerContent)); })); 13728 }; 13729 return TimeColMisc; 13730 }(BaseComponent)); 13731 13732 var TimeCol = /** @class */ (function (_super) { 13733 __extends(TimeCol, _super); 13734 function TimeCol() { 13735 var _this = _super !== null && _super.apply(this, arguments) || this; 13736 _this.sortEventSegs = memoize(sortEventSegs); 13737 return _this; 13738 } 13739 // TODO: memoize event-placement? 13740 TimeCol.prototype.render = function () { 13741 var _this = this; 13742 var _a = this, props = _a.props, context = _a.context; 13743 var isSelectMirror = context.options.selectMirror; 13744 var mirrorSegs = (props.eventDrag && props.eventDrag.segs) || 13745 (props.eventResize && props.eventResize.segs) || 13746 (isSelectMirror && props.dateSelectionSegs) || 13747 []; 13748 var interactionAffectedInstances = // TODO: messy way to compute this 13749 (props.eventDrag && props.eventDrag.affectedInstances) || 13750 (props.eventResize && props.eventResize.affectedInstances) || 13751 {}; 13752 var sortedFgSegs = this.sortEventSegs(props.fgEventSegs, context.options.eventOrder); 13753 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), 13754 createElement("div", { className: "fc-timegrid-col-frame" }, 13755 createElement("div", { className: "fc-timegrid-col-bg" }, 13756 _this.renderFillSegs(props.businessHourSegs, 'non-business'), 13757 _this.renderFillSegs(props.bgEventSegs, 'bg-event'), 13758 _this.renderFillSegs(props.dateSelectionSegs, 'highlight')), 13759 createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(sortedFgSegs, interactionAffectedInstances, false, false, false)), 13760 createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror))), 13761 createElement("div", { className: "fc-timegrid-now-indicator-container" }, _this.renderNowIndicator(props.nowIndicatorSegs)), 13762 createElement(TimeColMisc, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps })))); })); 13763 }; 13764 TimeCol.prototype.renderFgSegs = function (sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting) { 13765 var props = this.props; 13766 if (props.forPrint) { 13767 return renderPlainFgSegs(sortedFgSegs, props); 13768 } 13769 return this.renderPositionedFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting); 13770 }; 13771 TimeCol.prototype.renderPositionedFgSegs = function (segs, // if not mirror, needs to be sorted 13772 segIsInvisible, isDragging, isResizing, isDateSelecting) { 13773 var _this = this; 13774 var _a = this.context.options, eventMaxStack = _a.eventMaxStack, eventShortHeight = _a.eventShortHeight, eventOrderStrict = _a.eventOrderStrict, eventMinHeight = _a.eventMinHeight; 13775 var _b = this.props, date = _b.date, slatCoords = _b.slatCoords, eventSelection = _b.eventSelection, todayRange = _b.todayRange, nowDate = _b.nowDate; 13776 var isMirror = isDragging || isResizing || isDateSelecting; 13777 var segVCoords = computeSegVCoords(segs, date, slatCoords, eventMinHeight); 13778 var _c = computeFgSegPlacements(segs, segVCoords, eventOrderStrict, eventMaxStack), segPlacements = _c.segPlacements, hiddenGroups = _c.hiddenGroups; 13779 return (createElement(Fragment, null, 13780 this.renderHiddenGroups(hiddenGroups, segs), 13781 segPlacements.map(function (segPlacement) { 13782 var seg = segPlacement.seg, rect = segPlacement.rect; 13783 var instanceId = seg.eventRange.instance.instanceId; 13784 var isVisible = isMirror || Boolean(!segIsInvisible[instanceId] && rect); 13785 var vStyle = computeSegVStyle(rect && rect.span); 13786 var hStyle = (!isMirror && rect) ? _this.computeSegHStyle(rect) : { left: 0, right: 0 }; 13787 var isInset = Boolean(rect) && rect.stackForward > 0; 13788 var isShort = Boolean(rect) && (rect.span.end - rect.span.start) < eventShortHeight; // look at other places for this problem 13789 return (createElement("div", { className: 'fc-timegrid-event-harness' + 13790 (isInset ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: __assign(__assign({ visibility: isVisible ? '' : 'hidden' }, vStyle), hStyle) }, 13791 createElement(TimeColEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, isShort: isShort }, getSegMeta(seg, todayRange, nowDate))))); 13792 }))); 13793 }; 13794 // will already have eventMinHeight applied because segInputs already had it 13795 TimeCol.prototype.renderHiddenGroups = function (hiddenGroups, segs) { 13796 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; 13797 return (createElement(Fragment, null, hiddenGroups.map(function (hiddenGroup) { 13798 var positionCss = computeSegVStyle(hiddenGroup.span); 13799 var hiddenSegs = compileSegsFromEntries(hiddenGroup.entries, segs); 13800 return (createElement(TimeColMoreLink, { key: buildIsoString(computeEarliestSegStart(hiddenSegs)), hiddenSegs: hiddenSegs, top: positionCss.top, bottom: positionCss.bottom, extraDateSpan: extraDateSpan, dateProfile: dateProfile, todayRange: todayRange, nowDate: n
13800owDate, eventSelection: eventSelection, eventDrag: eventDrag, eventResize: eventResize })); 13801 }))); 13802 }; 13803 TimeCol.prototype.renderFillSegs = function (segs, fillType) { 13804 var _a = this, props = _a.props, context = _a.context; 13805 var segVCoords = computeSegVCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight); // don't assume all populated 13806 var children = segVCoords.map(function (vcoords, i) { 13807 var seg = segs[i]; 13808 return (createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-timegrid-bg-harness", style: computeSegVStyle(vcoords) }, fillType === 'bg-event' ? 13809 createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, props.todayRange, props.nowDate))) : 13810 renderFill(fillType))); 13811 }); 13812 return createElement(Fragment, null, children); 13813 }; 13814 TimeCol.prototype.renderNowIndicator = function (segs) { 13815 var _a = this.props, slatCoords = _a.slatCoords, date = _a.date; 13816 if (!slatCoords) { 13817 return null; 13818 } 13819 return segs.map(function (seg, i) { return (createElement(NowIndicatorRoot, { isAxis: false, date: date, 13820 // key doesn't matter. will only ever be one 13821 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)); })); }); 13822 }; 13823 TimeCol.prototype.computeSegHStyle = function (segHCoords) { 13824 var _a = this.context, isRtl = _a.isRtl, options = _a.options; 13825 var shouldOverlap = options.slotEventOverlap; 13826 var nearCoord = segHCoords.levelCoord; // the left side if LTR. the right side if RTL. floating-point 13827 var farCoord = segHCoords.levelCoord + segHCoords.thickness; // the right side if LTR. the left side if RTL. floating-point 13828 var left; // amount of space from left edge, a fraction of the total width 13829 var right; // amount of space from right edge, a fraction of the total width 13830 if (shouldOverlap) { 13831 // double the width, but don't go beyond the maximum forward coordinate (1.0) 13832 farCoord = Math.min(1, nearCoord + (farCoord - nearCoord) * 2); 13833 } 13834 if (isRtl) { 13835 left = 1 - farCoord; 13836 right = nearCoord; 13837 } 13838 else { 13839 left = nearCoord; 13840 right = 1 - farCoord; 13841 } 13842 var props = { 13843 zIndex: segHCoords.stackDepth + 1, 13844 left: left * 100 + '%', 13845 right: right * 100 + '%', 13846 }; 13847 if (shouldOverlap && !segHCoords.stackForward) { 13848 // add padding to the edge so that forward stacked events don't cover the resizer's icon 13849 props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width 13850 } 13851 return props; 13852 }; 13853 return TimeCol; 13854 }(BaseComponent)); 13855 function renderPlainFgSegs(sortedFgSegs, _a) { 13856 var todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize; 13857 var hiddenInstances = (eventDrag ? eventDrag.affectedInstances : null) || 13858 (eventResize ? eventResize.affectedInstances : null) || 13859 {}; 13860 return (createElement(Fragment, null, sortedFgSegs.map(function (seg) { 13861 var instanceId = seg.eventRange.instance.instanceId; 13862 return (createElement("div", { key: instanceId, style: { visibility: hiddenInstances[instanceId] ? 'hidden' : '' } }, 13863 createElement(TimeColEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === eventSelection, isShort: false }, getSegMeta(seg, todayRange, nowDate))))); 13864 }))); 13865 } 13866 function computeSegVStyle(segVCoords) { 13867 if (!segVCoords) { 13868 return { top: '', bottom: '' }; 13869 } 13870 return { 13871 top: segVCoords.start, 13872 bottom: -segVCoords.end, 13873 }; 13874 } 13875 function compileSegsFromEntries(segEntries, allSegs) { 13876 return segEntries.map(function (segEntry) { return allSegs[segEntry.index]; }); 13877 } 13878 13879 var TimeColsContent = /** @class */ (function (_super) { 13880 __extends(TimeColsContent, _super); 13881 function TimeColsContent() { 13882 var _this = _super !== null && _super.apply(this, arguments) || this; 13883 _this.splitFgEventSegs = memoize(splitSegsByCol); 13884 _this.splitBgEventSegs = memoize(splitSegsByCol); 13885 _this.splitBusinessHourSegs = memoize(splitSegsByCol); 13886 _this.splitNowIndicatorSegs = memoize(splitSegsByCol); 13887 _this.splitDateSelectionSegs = memoize(splitSegsByCol); 13888 _this.splitEventDrag = memoize(splitInteractionByCol); 13889 _this.splitEventResize = memoize(splitInteractionByCol); 13890 _this.rootElRef = createRef(); 13891 _this.cellElRefs = new RefMap(); 13892 return _this; 13893 } 13894 TimeColsContent.prototype.render = function () { 13895 var _this = this; 13896 var _a = this, props = _a.props, context = _a.context; 13897 var nowIndicatorTop = context.options.nowIndicator && 13898 props.slatCoords && 13899 props.slatCoords.safeComputeTop(props.nowDate); // might return void 13900 var colCnt = props.cells.length; 13901 var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt); 13902 var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt); 13903 var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt); 13904 var nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt); 13905 var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt); 13906 var eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt); 13907 var eventResizeByRow = this.splitEventResize(props.eventResize, colCnt); 13908 return (createElement("div", { className: "fc-timegrid-cols", ref: this.rootElRef }, 13909 createElement("table", { role: "presentation", style: { 13910 minWidth: props.tableMinWidth, 13911 width: props.clientWidth, 13912 } },
13913 props.tableColGroupNode, 13914 createElement("tbody", { role: "presentation" }, 13915 createElement("tr", { role: "row" }, 13916 props.axis && (createElement("td", { "aria-hidden": true, className: "fc-timegrid-col fc-timegrid-axis" }, 13917 createElement("div", { className: "fc-timegrid-col-frame" }, 13918 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)); })))))), 13919 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 })); })))))); 13920 }; 13921 TimeColsContent.prototype.componentDidMount = function () { 13922 this.updateCoords(); 13923 }; 13924 TimeColsContent.prototype.componentDidUpdate = function () { 13925 this.updateCoords(); 13926 }; 13927 TimeColsContent.prototype.updateCoords = function () { 13928 var props = this.props; 13929 if (props.onColCoords && 13930 props.clientWidth !== null // means sizing has stabilized 13931 ) { 13932 props.onColCoords(new PositionCache(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal 13933 false)); 13934 } 13935 }; 13936 return TimeColsContent; 13937 }(BaseComponent)); 13938 function collectCellEls(elMap, cells) { 13939 return cells.map(function (cell) { return elMap[cell.key]; }); 13940 } 13941 13942 /* A component that renders one or more columns of vertical time slots 13943 ----------------------------------------------------------------------------------------------------------------------*/ 13944 var TimeCols = /** @class */ (function (_super) { 13945 __extends(TimeCols, _super); 13946 function TimeCols() { 13947 var _this = _super !== null && _super.apply(this, arguments) || this; 13948 _this.processSlotOptions = memoize(processSlotOptions); 13949 _this.state = { 13950 slatCoords: null, 13951 }; 13952 _this.handleRootEl = function (el) { 13953 if (el) { 13954 _this.context.registerInteractiveComponent(_this, { 13955 el: el, 13956 isHitComboAllowed: _this.props.isHitComboAllowed, 13957 }); 13958 } 13959 else { 13960 _this.context.unregisterInteractiveComponent(_this); 13961 } 13962 }; 13963 _this.handleScrollRequest = function (request) { 13964 var onScrollTopRequest = _this.props.onScrollTopRequest; 13965 var slatCoords = _this.state.slatCoords; 13966 if (onScrollTopRequest && slatCoords) { 13967 if (request.time) { 13968 var top_1 = slatCoords.computeTimeTop(request.time); 13969 top_1 = Math.ceil(top_1); // zoom can give weird floating-point values. rather scroll a little bit further 13970 if (top_1) { 13971 top_1 += 1; // to overcome top border that slots beyond the first have. looks better 13972 } 13973 onScrollTopRequest(top_1); 13974 } 13975 return true; 13976 } 13977 return false;
13978 }; 13979 _this.handleColCoords = function (colCoords) { 13980 _this.colCoords = colCoords; 13981 }; 13982 _this.handleSlatCoords = function (slatCoords) { 13983 _this.setState({ slatCoords: slatCoords }); 13984 if (_this.props.onSlatCoords) { 13985 _this.props.onSlatCoords(slatCoords); 13986 } 13987 }; 13988 return _this; 13989 } 13990 TimeCols.prototype.render = function () { 13991 var _a = this, props = _a.props, state = _a.state; 13992 return (createElement("div", { className: "fc-timegrid-body", ref: this.handleRootEl, style: { 13993 // these props are important to give this wrapper correct dimensions for interactions 13994 // TODO: if we set it here, can we avoid giving to inner tables? 13995 width: props.clientWidth, 13996 minWidth: props.tableMinWidth, 13997 } }, 13998 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 }), 13999 createElement(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bg
13999EventSegs, 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 }))); 14000 }; 14001 TimeCols.prototype.componentDidMount = function () { 14002 this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest); 14003 }; 14004 TimeCols.prototype.componentDidUpdate = function (prevProps) { 14005 this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile); 14006 }; 14007 TimeCols.prototype.componentWillUnmount = function () { 14008 this.scrollResponder.detach(); 14009 }; 14010 TimeCols.prototype.queryHit = function (positionLeft, positionTop) { 14011 var _a = this.context, dateEnv = _a.dateEnv, options = _a.options; 14012 var colCoords = this.colCoords; 14013 var dateProfile = this.props.dateProfile; 14014 var slatCoords = this.state.slatCoords; 14015 var _b = this.processSlotOptions(this.props.slotDuration, options.snapDuration), snapDuration = _b.snapDuration, snapsPerSlot = _b.snapsPerSlot; 14016 var colIndex = colCoords.leftToIndex(positionLeft); 14017 var slatIndex = slatCoords.positions.topToIndex(positionTop); 14018 if (colIndex != null && slatIndex != null) { 14019 var cell = this.props.cells[colIndex]; 14020 var slatTop = slatCoords.positions.tops[slatIndex]; 14021 var slatHeight = slatCoords.positions.getHeight(slatIndex); 14022 var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1 14023 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat 14024 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex; 14025 var dayDate = this.props.cells[colIndex].date; 14026 var time = addDurations(dateProfile.slotMinTime, multiplyDuration(snapDuration, snapIndex)); 14027 var start = dateEnv.add(dayDate, time); 14028 var end = dateEnv.add(start, snapDuration); 14029 return { 14030 dateProfile: dateProfile, 14031 dateSpan: __assign({ range: { start: start, end: end }, allDay: false }, cell.extraDateSpan), 14032 dayEl: colCoords.els[colIndex], 14033 rect: { 14034 left: colCoords.lefts[colIndex], 14035 right: colCoords.rights[colIndex], 14036 top: slatTop, 14037 bottom: slatTop + slatHeight, 14038 }, 14039 layer: 0, 14040 }; 14041 } 14042 return null; 14043 }; 14044 return TimeCols; 14045 }(DateComponent)); 14046 function processSlotOptions(slotDuration, snapDurationOverride) { 14047 var snapDuration = snapDurationOverride || slotDuration; 14048 var snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration); 14049 if (snapsPerSlot === null) { 14050 snapDuration = slotDuration; 14051 snapsPerSlot = 1; 14052 // TODO: say warning? 14053 } 14054 return { snapDuration: snapDuration, snapsPerSlot: snapsPerSlot }; 14055 } 14056 14057 var DayTimeColsSlicer = /** @class */ (function (_super) { 14058 __extends(DayTimeColsSlicer, _super); 14059 function DayTimeColsSlicer() { 14060 return _super !== null && _super.apply(this, arguments) || this; 14061 } 14062 DayTimeColsSlicer.prototype.sliceRange = function (range, dayRanges) { 14063 var segs = []; 14064 for (var col = 0; col < dayRanges.length; col += 1) { 14065 var segRange = intersectRanges(range, dayRanges[col]); 14066 if (segRange) { 14067 segs.push({ 14068 start: segRange.start, 14069 end: segRange.end, 14070 isStart: segRange.start.valueOf() === range.start.valueOf(), 14071 isEnd: segRange.end.valueOf() === range.end.valueOf(), 14072 col: col, 14073 }); 14074 } 14075 } 14076 return segs; 14077 }; 14078 return DayTimeColsSlicer; 14079 }(Slicer)); 14080 14081 var DayTimeCols = /** @class */ (function (_super) { 14082 __extends(DayTimeCols, _super); 14083 function DayTimeCols() { 14084 var _this = _super !== null && _super.apply(this, arguments) || this; 14085 _this.buildDayRanges = memoize(buildDayRanges); 14086 _this.slicer = new DayTimeColsSlicer(); 14087 _this.timeColsRef = createRef(); 14088 return _this; 14089 } 14090 DayTimeCols.prototype.render = function () { 14091 var _this = this; 14092 var _a = this, props = _a.props, context = _a.context; 14093 var dateProfile = props.dateProfile, dayTableModel = props.dayTableModel; 14094 var isNowIndicator = context.options.nowIndicator; 14095 var dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv); 14096 // give it the first row of cells 14097 // TODO: would move this further down hierarchy, but sliceNowDate needs it 14098 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: n
14098owDate, nowIndicatorSegs: isNowIndicator && _this.slicer.sliceNowDate(nowDate, context, dayRanges), todayRange: todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords }))); })); 14099 }; 14100 return DayTimeCols; 14101 }(DateComponent)); 14102 function buildDayRanges(dayTableModel, dateProfile, dateEnv) { 14103 var ranges = []; 14104 for (var _i = 0, _a = dayTableModel.headerDates; _i < _a.length; _i++) { 14105 var date = _a[_i]; 14106 ranges.push({ 14107 start: dateEnv.add(date, dateProfile.slotMinTime), 14108 end: dateEnv.add(date, dateProfile.slotMaxTime), 14109 }); 14110 } 14111 return ranges; 14112 } 14113 14114 // potential nice values for the slot-duration and interval-duration 14115 // from largest to smallest 14116 var STOCK_SUB_DURATIONS = [ 14117 { hours: 1 }, 14118 { minutes: 30 }, 14119 { minutes: 15 }, 14120 { seconds: 30 }, 14121 { seconds: 15 }, 14122 ]; 14123 function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) { 14124 var dayStart = new Date(0); 14125 var slatTime = slotMinTime; 14126 var slatIterator = createDuration(0); 14127 var labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration); 14128 var metas = []; 14129 while (asRoughMs(slatTime) < asRoughMs(slotMaxTime)) { 14130 var date = dateEnv.add(dayStart, slatTime); 14131 var isLabeled = wholeDivideDurations(slatIterator, labelInterval) !== null; 14132 metas.push({ 14133 date: date, 14134 time: slatTime, 14135 key: date.toISOString(), 14136 isoTimeStr: formatIsoTimeString(date), 14137 isLabeled: isLabeled, 14138 }); 14139 slatTime = addDurations(slatTime, slotDuration); 14140 slatIterator = addDurations(slatIterator, slotDuration); 14141 } 14142 return metas; 14143 } 14144 // Computes an automatic value for slotLabelInterval 14145 function computeLabelInterval(slotDuration) { 14146 var i; 14147 var labelInterval; 14148 var slotsPerLabel; 14149 // find the smallest stock label interval that results in more than one slots-per-label 14150 for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i -= 1) { 14151 labelInterval = createDuration(STOCK_SUB_DURATIONS[i]); 14152 slotsPerLabel = wholeDivideDurations(labelInterval, slotDuration);
14153 if (slotsPerLabel !== null && slotsPerLabel > 1) { 14154 return labelInterval; 14155 } 14156 } 14157 return slotDuration; // fall back 14158 } 14159 14160 var DayTimeColsView = /** @class */ (function (_super) { 14161 __extends(DayTimeColsView, _super); 14162 function DayTimeColsView() { 14163 var _this = _super !== null && _super.apply(this, arguments) || this; 14164 _this.buildTimeColsModel = memoize(buildTimeColsModel); 14165 _this.buildSlatMetas = memoize(buildSlatMetas); 14166 return _this; 14167 } 14168 DayTimeColsView.prototype.render = function () { 14169 var _this = this; 14170 var _a = this.context, options = _a.options, dateEnv = _a.dateEnv, dateProfileGenerator = _a.dateProfileGenerator; 14171 var props = this.props; 14172 var dateProfile = props.dateProfile; 14173 var dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator); 14174 var splitProps = this.allDaySplitter.splitProps(props); 14175 var slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv); 14176 var dayMinWidth = options.dayMinWidth; 14177 var hasAttachedAxis = !dayMinWidth; 14178 var hasDetachedAxis = dayMinWidth; 14179 var headerContent = options.dayHeaders && (createElement(DayHeader, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null })); 14180 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()))); }); 14181 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 }))); }; 14182 return hasDetachedAxis 14183 ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords) 14184 : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent); 14185 }; 14186 return DayTimeColsView; 14187 }(TimeColsView));
14188 function buildTimeColsModel(dateProfile, dateProfileGenerator) { 14189 var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator); 14190 return new DayTableModel(daySeries, false); 14191 } 14192 14193 var OPTION_REFINERS$2 = { 14194 allDaySlot: Boolean, 14195 }; 14196 14197 var timeGridPlugin = createPlugin({ 14198 initialView: 'timeGridWeek', 14199 optionRefiners: OPTION_REFINERS$2, 14200 views: { 14201 timeGrid: { 14202 component: DayTimeColsView, 14203 usesMinMaxTime: true, 14204 allDaySlot: true, 14205 slotDuration: '00:30:00', 14206 slotEventOverlap: true, // a bad name. confused with overlap/constraint system 14207 }, 14208 timeGridDay: { 14209 type: 'timeGrid', 14210 duration: { days: 1 }, 14211 }, 14212 timeGridWeek: { 14213 type: 'timeGrid', 14214 duration: { weeks: 1 }, 14215 }, 14216 }, 14217 }); 14218 14219 var ListViewHeaderRow = /** @class */ (function (_super) { 14220 __extends(ListViewHeaderRow, _super); 14221 function ListViewHeaderRow() { 14222 var _this = _super !== null && _super.apply(this, arguments) || this; 14223 _this.state = { 14224 textId: getUniqueDomId(), 14225 }; 14226 return _this; 14227 } 14228 ListViewHeaderRow.prototype.render = function () { 14229 var _a = this.context, theme = _a.theme, dateEnv = _a.dateEnv, options = _a.options, viewApi = _a.viewApi; 14230 var _b = this.props, cellId = _b.cellId, dayDate = _b.dayDate, todayRange = _b.todayRange; 14231 var textId = this.state.textId; 14232 var dayMeta = getDateMeta(dayDate, todayRange); 14233 // will ever be falsy? 14234 var text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : ''; 14235 // will ever be falsy? also, BAD NAME "alt" 14236 var sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : ''; 14237 var hookProps = __assign({ date: dateEnv.toDate(dayDate), view: viewApi, textId: textId, 14238 text: text, 14239 sideText: sideText, navLinkAttrs: buildNavLinkAttrs(this.context, dayDate), sideNavLinkAttrs: buildNavLinkAttrs(this.context, dayDate, 'day', false) }, dayMeta); 14240 var classNames = ['fc-list-day'].concat(getDayClassNames(dayMeta, theme)); 14241 // TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too) 14242 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) }, 14243 createElement("th", { scope: "colgroup", colSpan: 3, id: cellId, "aria-labelledby": textId }, 14244 createElement("div", { className: 'fc-list-day-cushion ' + theme.getClass('tableCellShaded'), ref: innerElRef }, innerContent)))); })); 14245 }; 14246 return ListViewHeaderRow; 14247 }(BaseComponent)); 14248 function renderInnerContent(props) { 14249 return (createElement(Fragment, null, 14250 props.text && (createElement("a", __assign({ id: props.textId, className: "fc-list-day-text" }, props.navLinkAttrs), props.text)), 14251 props.sideText && ( /* not keyboard tabbable */createElement("a", __assign({ "aria-hidden": true, className: "fc-list-day-side-text" }, props.sideNavLinkAttrs), props.sideText)))); 14252 } 14253 14254 var DEFAULT_TIME_FORMAT = createFormatter({ 14255 hour: 'numeric', 14256 minute: '2-digit', 14257 meridiem: 'short', 14258 }); 14259 var ListViewEventRow = /** @class */ (function (_super) { 14260 __extends(ListViewEventRow, _super); 14261 function ListViewEventRow() { 14262 return _super !== null && _super.apply(this, arguments) || this; 14263 } 14264 ListViewEventRow.prototype.render = function () { 14265 var _a = this, props = _a.props, context = _a.context; 14266 var seg = props.seg, timeHeaderId = props.timeHeaderId, eventHeaderId = props.eventHeaderId, dateHeaderId = props.dateHeaderId; 14267 var timeFormat = context.options.eventTimeFormat || DEFAULT_TIME_FORMAT; 14268 return (createElement(EventRoot, { seg: seg, timeText: "" // BAD. because of all-day content 14269 , 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 }, 14270 buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId), 14271 createElement("td", { "aria-hidden": true, className: "fc-list-event-graphic" }, 14272 createElement("span", { className: "fc-list-event-dot", style: { borderColor: hookProps.borderColor || hookProps.backgroundColor } })), 14273 createElement("td", { ref: innerElRef, headers: eventHeaderId + " " + dateHeaderId, className: "fc-list-event-title" }, innerContent))); })); 14274 }; 14275 return ListViewEventRow; 14276 }(BaseComponent)); 14277 function renderEventInnerContent(seg, context) { 14278 var interactiveAttrs = getSegAnchorAttrs(seg, context); 14279 return (createElement("a", __assign({}, interactiveAttrs), seg.eventRange.def.title)); 14280 } 14281 function buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId) { 14282 var options = context.options; 14283 if (options.displayEventTime !== false) { 14284 var eventDef = seg.eventRange.def; 14285 var eventInstance = seg.eventRange.instance; 14286 var doAllDay = false;
14287 var timeText = void 0; 14288 if (eventDef.allDay) { 14289 doAllDay = true; 14290 } 14291 else if (isMultiDayRange(seg.eventRange.range)) { // TODO: use (!isStart || !isEnd) instead? 14292 if (seg.isStart) { 14293 timeText = buildSegTimeText(seg, timeFormat, context, null, null, eventInstance.range.start, seg.end); 14294 } 14295 else if (seg.isEnd) { 14296 timeText = buildSegTimeText(seg, timeFormat, context, null, null, seg.start, eventInstance.range.end); 14297 } 14298 else { 14299 doAllDay = true; 14300 } 14301 } 14302 else { 14303 timeText = buildSegTimeText(seg, timeFormat, context); 14304 } 14305 if (doAllDay) { 14306 var hookProps = { 14307 text: context.options.allDayText, 14308 view: context.viewApi, 14309 }; 14310 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)); })); 14311 } 14312 return (createElement("td", { className: "fc-list-event-time" }, timeText)); 14313 } 14314 return null; 14315 } 14316 function renderAllDayInner(hookProps) { 14317 return hookProps.text; 14318 } 14319 14320 /* 14321 Responsible for the scroller, and forwarding event-related actions into the "grid". 14322 */ 14323 var ListView = /** @class */ (function (_super) { 14324 __extends(ListView, _super); 14325 function ListView() { 14326 var _this = _super !== null && _super.apply(this, arguments) || this; 14327 _this.computeDateVars = memoize(computeDateVars); 14328 _this.eventStoreToSegs = memoize(_this._eventStoreToSegs); 14329 _this.state = { 14330 timeHeaderId: getUniqueDomId(), 14331 eventHeaderId: getUniqueDomId(), 14332 dateHeaderIdRoot: getUniqueDomId(), 14333 }; 14334 _this.setRootEl = function (rootEl) { 14335 if (rootEl) { 14336 _this.context.registerInteractiveComponent(_this, { 14337 el: rootEl, 14338 }); 14339 } 14340 else { 14341 _this.context.unregisterInteractiveComponent(_this); 14342 } 14343 }; 14344 return _this; 14345 } 14346 ListView.prototype.render = function () { 14347 var _this = this; 14348 var _a = this, props = _a.props, context = _a.context; 14349 var extraClassNames = [ 14350 'fc-list', 14351 context.theme.getClass('table'), 14352 context.options.stickyHeaderDates !== false ? 'fc-list-sticky' : '', 14353 ]; 14354 var _b = this.computeDateVars(props.dateProfile), dayDates = _b.dayDates, dayRanges = _b.dayRanges; 14355 var eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges); 14356 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.setRootEl }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: extraClassNames.concat(classNames).join(' ') }, 14357 createElement(Scroller, { liquid: !props.isHeightAuto, overflowX: props.isHeightAuto ? 'visible' : 'hidden', overflowY: props.isHeightAuto ? 'visible' : 'auto' }, eventSegs.length > 0 ? 14358 _this.renderSegList(eventSegs, dayDates) : 14359 _this.renderEmptyMessage()))); })); 14360 }; 14361 ListView.prototype.renderEmptyMessage = function () { 14362 var _a = this.context, options = _a.options, viewApi = _a.viewApi; 14363 var hookProps = { 14364 text: options.noEventsText, 14365 view: viewApi, 14366 }; 14367 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 }, 14368 createElement("div", { className: "fc-list-empty-cushion", ref: innerElRef }, innerContent))); })); 14369 }; 14370 ListView.prototype.renderSegList = function (allSegs, dayDates) { 14371 var _a = this.context, theme = _a.theme, options = _a.options; 14372 var _b = this.state, timeHeaderId = _b.timeHeaderId, eventHeaderId = _b.eventHeaderId, dateHeaderIdRoot = _b.dateHeaderIdRoot; 14373 var segsByDay = groupSegsByDay(allSegs); // sparse array 14374 return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { 14375 var innerNodes = []; 14376 for (var dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) { 14377 var daySegs = segsByDay[dayIndex]; 14378 if (daySegs) { // sparse array, so might be undefined 14379 var dayStr = formatDayString(dayDates[dayIndex]); 14380 var dateHeaderId = dateHeaderIdRoot + '-' + dayStr; 14381 // append a day header 14382 innerNodes.push(createElement(ListViewHeaderRow, { key: dayStr, cellId: dateHeaderId, dayDate: dayDates[dayIndex], todayRange: todayRange })); 14383 daySegs = sortEventSegs(daySegs, options.eventOrder);
14384 for (var _i = 0, daySegs_1 = daySegs; _i < daySegs_1.length; _i++) { 14385 var seg = daySegs_1[_i]; 14386 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)))); 14387 } 14388 } 14389 } 14390 return (createElement("table", { className: 'fc-list-table ' + theme.getClass('table') }, 14391 createElement("thead", null, 14392 createElement("tr", null, 14393 createElement("th", { scope: "col", id: timeHeaderId }, options.timeHint), 14394 createElement("th", { scope: "col", "aria-hidden": true }), 14395 createElement("th", { scope: "col", id: eventHeaderId }, options.eventHint))), 14396 createElement("tbody", null, innerNodes))); 14397 })); 14398 }; 14399 ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) { 14400 return this.eventRangesToSegs(sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges); 14401 }; 14402 ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) { 14403 var segs = []; 14404 for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) { 14405 var eventRange = eventRanges_1[_i]; 14406 segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges)); 14407 } 14408 return segs; 14409 }; 14410 ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) { 14411 var dateEnv = this.context.dateEnv; 14412 var nextDayThreshold = this.context.options.nextDayThreshold; 14413 var range = eventRange.range; 14414 var allDay = eventRange.def.allDay; 14415 var dayIndex; 14416 var segRange; 14417 var seg; 14418 var segs = []; 14419 for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) { 14420 segRange = intersectRanges(range, dayRanges[dayIndex]); 14421 if (segRange) { 14422 seg = { 14423 component: this, 14424 eventRange: eventRange, 14425 start: segRange.start, 14426 end: segRange.end, 14427 isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(), 14428 isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(), 14429 dayIndex: dayIndex, 14430 }; 14431 segs.push(seg); 14432 // detect when range won't go fully into the next day, 14433 // and mutate the latest seg to the be the end. 14434 if (!seg.isEnd && !allDay && 14435 dayIndex + 1 < dayRanges.length && 14436 range.end < 14437 dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) { 14438 seg.end = range.end; 14439 seg.isEnd = true; 14440 break; 14441 } 14442 } 14443 } 14444 return segs; 14445 }; 14446 return ListView; 14447 }(DateComponent)); 14448 function renderNoEventsInner(hookProps) { 14449 return hookProps.text; 14450 } 14451 function computeDateVars(dateProfile) { 14452 var dayStart = startOfDay(dateProfile.renderRange.start); 14453 var viewEnd = dateProfile.renderRange.end; 14454 var dayDates = []; 14455 var dayRanges = []; 14456 while (dayStart < viewEnd) { 14457 dayDates.push(dayStart); 14458 dayRanges.push({ 14459 start: dayStart, 14460 end: addDays(dayStart, 1), 14461 }); 14462 dayStart = addDays(dayStart, 1); 14463 } 14464 return { dayDates: dayDates, dayRanges: dayRanges }; 14465 } 14466 // Returns a sparse array of arrays, segs grouped by their dayIndex 14467 function groupSegsByDay(segs) { 14468 var segsByDay = []; // sparse array 14469 var i; 14470 var seg; 14471 for (i = 0; i < segs.length; i += 1) { 14472 seg = segs[i]; 14473 (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = [])) 14474 .push(seg); 14475 } 14476 return segsByDay; 14477 } 14478 14479 var OPTION_REFINERS$1 = { 14480 listDayFormat: createFalsableFormatter, 14481 listDaySideFormat: createFalsableFormatter, 14482 noEventsClassNames: identity, 14483 noEventsContent: identity, 14484 noEventsDidMount: identity, 14485 noEventsWillUnmount: identity, 14486 // noEventsText is defined in base options 14487 }; 14488 function createFalsableFormatter(input) { 14489 return input === false ? null : createFormatter(input); 14490 } 14491 14492 var listPlugin = createPlugin({ 14493 optionRefiners: OPTION_REFINERS$1, 14494 views: { 14495 list: { 14496 component: ListView, 14497 buttonTextKey: 'list', 14498 listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' }, // like "January 1, 2016" 14499 }, 14500 listDay: { 14501 type: 'list', 14502 duration: { days: 1 }, 14503 listDayFormat: { weekday: 'long' }, // day-of-week is all we need. full date is probably in headerToolbar 14504 }, 14505 listWeek: { 14506 type: 'list', 14507 duration: { weeks: 1 }, 14508 listDayFormat: { weekday: 'long' }, 14509 listDaySideFormat: { month: 'long', day: 'numeric', year: 'numeric' }, 14510 }, 14511 listMonth: { 14512 type: 'list', 14513 duration: { month: 1 }, 14514 listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have 14515 }, 14516 listYear: { 14517 type: 'list', 14518 duration: { year: 1 }, 14519 listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have 14520 }, 14521 }, 14522 }); 14523 14524 var BootstrapTheme = /** @class */ (function (_super) { 14525 __extends(BootstrapTheme, _super); 14526 function BootstrapTheme() { 14527 return _super !== null && _super.apply(this, arguments) || this; 14528 } 14529 return BootstrapTheme; 14530 }(Theme)); 14531 BootstrapTheme.prototype.classes = { 14532 root: 'fc-theme-bootstrap', 14533 table: 'table-bordered', 14534 tableCellShaded: 'table-active', 14535 buttonGroup: 'btn-group', 14536 button: 'btn btn-primary', 14537 buttonActive: 'active', 14538 popover: 'popover', 14539 popoverHeader: 'popover-header', 14540 popoverContent: 'popover-body', 14541 }; 14542 BootstrapTheme.prototype.baseIconClass = 'fa'; 14543 BootstrapTheme.prototype.iconClasses = { 14544 close: 'fa-times', 14545 prev: 'fa-chevron-left', 14546 next: 'fa-chevron-right', 14547 prevYear: 'fa-angle-double-left', 14548 nextYear: 'fa-angle-double-right', 14549 }; 14550 BootstrapTheme.prototype.rtlIconClasses = { 14551 prev: 'fa-chevron-right', 14552 next: 'fa-chevron-left', 14553 prevYear: 'fa-angle-double-right', 14554 nextYear: 'fa-angle-double-left', 14555 }; 14556 BootstrapTheme.prototype.iconOverrideOption = 'bootstrapFontAwesome';
14556 // TODO: make TS-friendly. move the option-processing into this plugin 14557 BootstrapTheme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome'; 14558 BootstrapTheme.prototype.iconOverridePrefix = 'fa-'; 14559 var plugin = createPlugin({ 14560 themeClasses: { 14561 bootstrap: BootstrapTheme, 14562 }, 14563 }); 14564 14565 // rename this file to options.ts like other packages? 14566 var OPTION_REFINERS = { 14567 googleCalendarApiKey: String, 14568 }; 14569 14570 var EVENT_SOURCE_REFINERS = { 14571 googleCalendarApiKey: String, 14572 googleCalendarId: String, 14573 googleCalendarApiBase: String, 14574 extraParams: identity, 14575 }; 14576 14577 // TODO: expose somehow 14578 var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars'; 14579 var eventSourceDef = { 14580 parseMeta: function (refined) { 14581 var googleCalendarId = refined.googleCalendarId; 14582 if (!googleCalendarId && refined.url) { 14583 googleCalendarId = parseGoogleCalendarId(refined.url); 14584 } 14585 if (googleCalendarId) { 14586 return { 14587 googleCalendarId: googleCalendarId, 14588 googleCalendarApiKey: refined.googleCalendarApiKey, 14589 googleCalendarApiBase: refined.googleCalendarApiBase, 14590 extraParams: refined.extraParams, 14591 }; 14592 } 14593 return null; 14594 }, 14595 fetch: function (arg, onSuccess, onFailure) { 14596 var _a = arg.context, dateEnv = _a.dateEnv, options = _a.options; 14597 var meta = arg.eventSource.meta; 14598 var apiKey = meta.googleCalendarApiKey || options.googleCalendarApiKey; 14599 if (!apiKey) { 14600 onFailure({ 14601 message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/', 14602 }); 14603 } 14604 else { 14605 var url = buildUrl(meta); 14606 // TODO: make DRY with json-feed-event-source 14607 var extraParams = meta.extraParams; 14608 var extraParamsObj = typeof extraParams === 'function' ? extraParams() : extraParams; 14609 var requestParams_1 = buildRequestParams(arg.range, apiKey, extraParamsObj, dateEnv); 14610 requestJson('GET', url, requestParams_1, function (body, xhr) { 14611 if (body.error) { 14612 onFailure({ 14613 message: 'Google Calendar API: ' + body.error.message, 14614 errors: body.error.errors, 14615 xhr: xhr, 14616 }); 14617 } 14618 else { 14619 onSuccess({ 14620 rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone), 14621 xhr: xhr, 14622 }); 14623 } 14624 }, function (message, xhr) { 14625 onFailure({ message: message, xhr: xhr }); 14626 }); 14627 } 14628 }, 14629 }; 14630 function parseGoogleCalendarId(url) { 14631 var match; 14632 // detect if the ID was specified as a single string. 14633 // will match calendars like "[email protected]" in addition to person email calendars. 14634 if (/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) { 14635 return url; 14636 } 14637 if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec(url)) || 14638 (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(url))) { 14639 return decodeURIComponent(match[1]); 14640 } 14641 return null; 14642 } 14643 function buildUrl(meta) { 14644 var apiBase = meta.googleCalendarApiBase; 14645 if (!apiBase) { 14646 apiBase = API_BASE; 14647 } 14648 return apiBase + '/' + encodeURIComponent(meta.googleCalendarId) + '/events'; 14649 } 14650 function buildRequestParams(range, apiKey, extraParams, dateEnv) { 14651 var params; 14652 var startStr; 14653 var endStr; 14654 if (dateEnv.canComputeOffset) { 14655 // strings will naturally have offsets, which GCal needs 14656 startStr = dateEnv.formatIso(range.start); 14657 endStr = dateEnv.formatIso(range.end); 14658 } 14659 else {
14660 // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day 14661 // from the UTC day-start to guarantee we're getting all the events 14662 // (start/end will be UTC-coerced dates, so toISOString is okay) 14663 startStr = addDays(range.start, -1).toISOString(); 14664 endStr = addDays(range.end, 1).toISOString(); 14665 } 14666 params = __assign(__assign({}, (extraParams || {})), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 }); 14667 if (dateEnv.timeZone !== 'local') { 14668 params.timeZone = dateEnv.timeZone; 14669 } 14670 return params; 14671 } 14672 function gcalItemsToRawEventDefs(items, gcalTimezone) { 14673 return items.map(function (item) { return gcalItemToRawEventDef(item, gcalTimezone); }); 14674 } 14675 function gcalItemToRawEventDef(item, gcalTimezone) { 14676 var url = item.htmlLink || null; 14677 // make the URLs for each event show times in the correct timezone 14678 if (url && gcalTimezone) { 14679 url = injectQsComponent(url, 'ctz=' + gcalTimezone); 14680 } 14681 return { 14682 id: item.id, 14683 title: item.summary, 14684 start: item.start.dateTime || item.start.date, 14685 end: item.end.dateTime || item.end.date, 14686 url: url, 14687 location: item.location, 14688 description: item.description, 14689 attachments: item.attachments || [], 14690 extendedProps: (item.extendedProperties || {}).shared || {}, 14691 }; 14692 } 14693 // Injects a string like "arg=value" into the querystring of a URL 14694 // TODO: move to a general util file? 14695 function injectQsComponent(url, component) { 14696 // inject it after the querystring but before the fragment 14697 return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) { return (qs ? qs + '&' : '?') + component + hash; }); 14698 } 14699 var googleCalendarPlugin = createPlugin({ 14700 eventSourceDefs: [eventSourceDef], 14701 optionRefiners: OPTION_REFINERS, 14702 eventSourceRefiners: EVENT_SOURCE_REFINERS, 14703 }); 14704 14705 globalPlugins.push(interactionPlugin, dayGridPlugin, timeGridPlugin, listPlugin, plugin, googleCalendarPlugin); 14706 14707 exports.BASE_OPTION_DEFAULTS = BASE_OPTION_DEFAULTS; 14708 exports.BASE_OPTION_REFINERS = BASE_OPTION_REFINERS; 14709 exports.BaseComponent = BaseComponent; 14710 exports.BgEvent = BgEvent; 14711 exports.BootstrapTheme = BootstrapTheme; 14712 exports.Calendar = Calendar; 14713 exports.CalendarApi = CalendarApi; 14714 exports.CalendarContent = CalendarContent; 14715 exports.CalendarDataManager = CalendarDataManager; 14716 exports.CalendarDataProvider = CalendarDataProvider; 14717 exports.CalendarRoot = CalendarRoot; 14718 exports.Component = Component; 14719 exports.ContentHook = ContentHook; 14720 exports.CustomContentRenderContext = CustomContentRenderContext; 14721 exports.DateComponent = DateComponent; 14722 exports.DateEnv = DateEnv; 14723 exports.DateProfileGenerator = DateProfileGenerator; 14724 exports.DayCellContent = DayCellContent; 14725 exports.DayCellRoot = DayCellRoot; 14726 exports.DayGridView = DayTableView; 14727 exports.DayHeader = DayHeader;
14728 exports.DaySeriesModel = DaySeriesModel; 14729 exports.DayTable = DayTable; 14730 exports.DayTableModel = DayTableModel; 14731 exports.DayTableSlicer = DayTableSlicer; 14732 exports.DayTimeCols = DayTimeCols; 14733 exports.DayTimeColsSlicer = DayTimeColsSlicer; 14734 exports.DayTimeColsView = DayTimeColsView; 14735 exports.DelayedRunner = DelayedRunner; 14736 exports.Draggable = ExternalDraggable; 14737 exports.ElementDragging = ElementDragging; 14738 exports.ElementScrollController = ElementScrollController; 14739 exports.Emitter = Emitter; 14740 exports.EventApi = EventApi; 14741 exports.EventRoot = EventRoot; 14742 exports.EventSourceApi = EventSourceApi; 14743 exports.FeaturefulElementDragging = FeaturefulElementDragging; 14744 exports.Fragment = Fragment; 14745 exports.Interaction = Interaction; 14746 exports.ListView = ListView; 14747 exports.MoreLinkRoot = MoreLinkRoot; 14748 exports.MountHook = MountHook; 14749 exports.NamedTimeZoneImpl = NamedTimeZoneImpl; 14750 exports.NowIndicatorRoot = NowIndicatorRoot; 14751 exports.NowTimer = NowTimer; 14752 exports.PointerDragging = PointerDragging; 14753 exports.PositionCache = PositionCache; 14754 exports.RefMap = RefMap; 14755 exports.RenderHook = RenderHook; 14756 exports.ScrollController = ScrollController; 14757 exports.ScrollResponder = ScrollResponder; 14758 exports.Scroller = Scroller; 14759 exports.SegHierarchy = SegHierarchy; 14760 exports.SimpleScrollGrid = SimpleScrollGrid; 14761 exports.Slicer = Slicer; 14762 exports.Splitter = Splitter; 14763 exports.StandardEvent = StandardEvent; 14764 exports.Table = Table; 14765 exports.TableDateCell = TableDateCell; 14766 exports.TableDowCell = TableDowCell; 14767 exports.TableView = TableView; 14768 exports.Theme = Theme; 14769 exports.ThirdPartyDraggable = ThirdPartyDraggable; 14770 exports.TimeCols = TimeCols; 14771 exports.TimeColsSlatsCoords = TimeColsSlatsCoords; 14772 exports.TimeColsView = TimeColsView; 14773 exports.ViewApi = ViewApi; 14774 exports.ViewContextType = ViewContextType; 14775 exports.ViewRoot = ViewRoot; 14776 exports.WeekNumberRoot = WeekNumberRoot; 14777 exports.WindowScrollController = WindowScrollController; 14778 exports.addDays = addDays; 14779 exports.addDurations = addDurations; 14780 exports.addMs = addMs; 14781 exports.addWeeks = addWeeks; 14782 exports.allowContextMenu = allowContextMenu; 14783 exports.allowSelection = allowSelection; 14784 exports.applyMutationToEventStore = applyMutationToEventStore; 14785 exports.applyStyle = applyStyle; 14786 exports.applyStyleProp = applyStyleProp; 14787 exports.asCleanDays = asCleanDays; 14788 exports.asRoughMinutes = asRoughMinutes; 14789 exports.asRoughMs = asRoughMs; 14790 exports.asRoughSeconds = asRoughSeconds; 14791 exports.binarySearch = binarySearch; 14792 exports.buildClassNameNormalizer = buildClassNameNormalizer; 14793 exports.buildDayRanges = buildDayRanges; 14794 exports.buildDayTableModel = buildDayTableModel; 14795 exports.buildEntryKey = buildEntryKey; 14796 exports.buildEventApis = buildEventApis; 14797 exports.buildEventRangeKey = buildEventRangeKey; 14798 exports.buildHashFromArray = buildHashFromArray; 14799 exports.buildIsoString = buildIsoString; 14800 exports.buildNavLinkAttrs = buildNavLinkAttrs; 14801 exports.buildSegCompareObj = buildSegCompareObj; 14802 exports.buildSegTimeText = buildSegTimeText; 14803 exports.buildSlatMetas = buildSlatMetas; 14804 exports.buildTimeColsModel = buildTimeColsModel; 14805 exports.collectFromHash = collectFromHash; 14806 exports.combineEventUis = combineEventUis; 14807 exports.compareByFieldSpec = compareByFieldSpec; 14808 exports.compareByFieldSpecs = compareByFieldSpecs; 14809 exports.compareNumbers = compareNumbers; 14810 exports.compareObjs = compareObjs; 14811 exports.computeEarliestSegStart = computeEarliestSegStart; 14812 exports.computeEdges = computeEdges; 14813 exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat; 14814 exports.computeHeightAndMargins = computeHeightAndMargins; 14815 exports.computeInnerRect = computeInnerRect; 14816 exports.computeRect = computeRect; 14817 exports.computeSegDraggable = computeSegDraggable; 14818 exports.computeSegEndResizable = computeSegEndResizable; 14819 exports.computeSegStartResizable = computeSegStartResizable; 14820 exports.computeShrinkWidth = computeShrinkWidth; 14821 exports.computeSmallestCellWidth = computeSmallestCellWidth; 14822 exports.computeVisibleDayRange = computeVisibleDayRange; 14823 exports.config = config; 14824 exports.constrainPoint = constrainPoint; 14825 exports.createAriaClickAttrs = createAriaClickAttrs; 14826 exports.createContext = createContext; 14827 exports.createDuration = createDuration; 14828 exports.createElement = createElement; 14829 exports.createEmptyEventStore = createEmptyEventStore; 14830 exports.createEventInstance = createEventInstance; 14831 exports.createEventUi = createEventUi; 14832 exports.createFormatter = createFormatter; 14833 exports.createPlugin = createPlugin; 14834 exports.createPortal = createPortal; 14835 exports.createRef = createRef; 14836 exports.diffDates = diffDates; 14837 exports.diffDayAndTime = diffDayAndTime; 14838 exports.diffDays = diffDays; 14839 exports.diffPoints = diffPoints; 14840 exports.diffWeeks = diffWeeks; 14841 exports.diffWholeDays = diffWholeDays; 14842 exports.diffWholeWeeks = diffWholeWeeks; 14843 exports.disableCursor = disableCursor; 14844 exports.elementClosest = elementClosest; 14845 exports.elementMatches = elementMatches; 14846 exports.enableCursor = enableCursor; 14847 exports.eventTupleToStore = eventTupleToStore; 14848 exports.filterEventStoreDefs = filterEventStoreDefs; 14849 exports.filterHash = filterHash; 14850 exports.findDirectChildren = findDirectChildren; 14851 exports.findElements = findElements; 14852 exports.flexibleCompare = flexibleCompare; 14853 exports.flushToDom = flushToDom; 14854 exports.formatDate = formatDate; 14855 exports.formatDayString = formatDayString; 14856 exports.formatIsoTimeString = formatIsoTimeString; 14857 exports.formatRange = formatRange; 14858 exports.getAllowYScrolling = getAllowYScrolling; 14859 exports.getCanVGrowWithinCell = getCanVGrowWithinCell; 14860 exports.getClippingParents = getClippingParents; 14861 exports.getDateMeta = getDateMeta; 14862 exports.getDayClassNames = getDayClassNames; 14863 exports.getDefaultEventEnd = getDefaultEventEnd; 14864 exports.getElRoot = getElRoot; 14865 exports.getElSeg = getElSeg; 14866 exports.getEntrySpanEnd = getEntrySpanEnd; 14867 exports.getEventClassNames = getEventClassNames; 14868 exports.getEventTargetViaRoot = getEventTargetViaRoot; 14869 exports.getIsRtlScrollbarOnLeft = getIsRtlScrollbarOnLeft; 14870 exports.getRectCenter = getRectCenter; 14871 exports.getRelevantEvents = getRelevantEvents; 14872 exports.getScrollGridClassNames = getScrollGridClassNames;
14873 exports.getScrollbarWidths = getScrollbarWidths; 14874 exports.getSectionClassNames = getSectionClassNames; 14875 exports.getSectionHasLiquidHeight = getSectionHasLiquidHeight; 14876 exports.getSegAnchorAttrs = getSegAnchorAttrs; 14877 exports.getSegMeta = getSegMeta; 14878 exports.getSlotClassNames = getSlotClassNames; 14879 exports.getStickyFooterScrollbar = getStickyFooterScrollbar; 14880 exports.getStickyHeaderDates = getStickyHeaderDates; 14881 exports.getUnequalProps = getUnequalProps; 14882 exports.getUniqueDomId = getUniqueDomId; 14883 exports.globalLocales = globalLocales; 14884 exports.globalPlugins = globalPlugins; 14885 exports.greatestDurationDenominator = greatestDurationDenominator; 14886 exports.groupIntersectingEntries = groupIntersectingEntries; 14887 exports.guid = guid; 14888 exports.hasBgRendering = hasBgRendering; 14889 exports.hasShrinkWidth = hasShrinkWidth; 14890 exports.identity = identity; 14891 exports.interactionSettingsStore = interactionSettingsStore; 14892 exports.interactionSettingsToStore = interactionSettingsToStore; 14893 exports.intersectRanges = intersectRanges; 14894 exports.intersectRects = intersectRects; 14895 exports.intersectSpans = intersectSpans; 14896 exports.isArraysEqual = isArraysEqual; 14897 exports.isColPropsEqual = isColPropsEqual; 14898 exports.isDateSelectionValid = isDateSelectionValid; 14899 exports.isDateSpansEqual = isDateSpansEqual; 14900 exports.isInt = isInt; 14901 exports.isInteractionValid = isInteractionValid; 14902 exports.isMultiDayRange = isMultiDayRange; 14903 exports.isPropsEqual = isPropsEqual; 14904 exports.isPropsValid = isPropsValid; 14905 exports.isValidDate = isValidDate; 14906 exports.joinSpans = joinSpans; 14907 exports.listenBySelector = listenBySelector; 14908 exports.mapHash = mapHash; 14909 exports.memoize = memoize; 14910 exports.memoizeArraylike = memoizeArraylike; 14911 exports.memoizeHashlike = memoizeHashlike; 14912 exports.memoizeObjArg = memoizeObjArg; 14913 exports.mergeEventStores = mergeEventStores; 14914 exports.multiplyDuration = multiplyDuration; 14915 exports.padStart = padStart; 14916 exports.parseBusinessHours = parseBusinessHours; 14917 exports.parseClassNames = parseClassNames; 14918 exports.parseDragMeta = parseDragMeta; 14919 exports.parseEventDef = parseEventDef; 14920 exports.parseFieldSpecs = parseFieldSpecs; 14921 exports.parseMarker = parse; 14922 exports.pointInsideRect = pointInsideRect; 14923 exports.preventContextMenu = preventContextMenu; 14924 exports.preventDefault = preventDefault; 14925 exports.preventSelection = preventSelection; 14926 exports.rangeContainsMarker = rangeContainsMarker; 14927 exports.rangeContainsRange = rangeContainsRange; 14928 exports.rangesEqual = rangesEqual; 14929 exports.rangesIntersect = rangesIntersect; 14930 exports.refineEventDef = refineEventDef; 14931 exports.refineProps = refineProps; 14932 exports.removeElement = removeElement; 14933 exports.removeExact = removeExact; 14934 exports.render = render; 14935 exports.renderChunkContent = renderChunkContent; 14936 exports.renderFill = renderFill; 14937 exports.renderMicroColGroup = renderMicroColGroup; 14938 exports.renderScrollShim = renderScrollShim; 14939 exports.requestJson = requestJson; 14940 exports.sanitizeShrinkWidth = sanitizeShrinkWidth; 14941 exports.setElSeg = setElSeg; 14942 exports.setRef = setRef; 14943 exports.sliceEventStore = sliceEventStore; 14944 exports.sliceEvents = sliceEvents; 14945 exports.sortEventSegs = sortEventSegs; 14946 exports.startOfDay = startOfDay; 14947 exports.translateRect = translateRect; 14948 exports.triggerDateSelect = triggerDateSelect; 14949 exports.unmountComponentAtNode = unmountComponentAtNode; 14950 exports.unpromisify = unpromisify; 14951 exports.version = version; 14952 exports.whenTransitionDone = whenTransitionDone; 14953 exports.wholeDivideDurations = wholeDivideDurations; 14954 14955 Object.defineProperty(exports, '__esModule', { value: true }); 14956 14957 return exports; 14958 14959}({}));
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.